1 条题解
-
0
自动搬运
来自洛谷,原作者为

K8He
あぁ! 夏を今もう一回搬运于
2025-08-24 22:28:34,当前版本为作者最后更新于2021-02-06 14:12:12,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
神奇的5分算法:直接输出样例。20分算法
直接把每个点是否有牛的状态DFS一遍同时判断是否合法,时间复杂度约为(因为有判断合法的剪枝所以会比这个低)。而在前四个测试点中,用枚举算法在最坏情况下需要运行次,时间非常富裕,但是在之后的测试点中就会超时了。
50分算法
每四个方格内都有种方法放置牛:
1 2 3 4 5 6 CC C. C. .C .C .. .. C. .C C. .C CCDFS每四个方格内的六种情况同时判断是否合法,时间复杂度约为(因为有判断合法的剪枝所以会比这个低)。 部分参考代码:
int a[1001][1001],ans,n; char v[1001][1001]; string d[]={"cc00","c0c0","c00c","0cc0","0c0c","00cc"}; int dx[]={0,0,1,1}; int dy[]={0,1,0,1}; void dfs(int x,int y){ int nextx=x,nexty=y+1; if(nexty==n) nextx++,nexty = 1; if(x>=n){ int newscore=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) newscore+=v[i][j]=='c'?a[i][j]:0; ans=max(ans,newscore);//更新答案 return; } for(int i=0;i<6;i++){ int match=true; string old=""; for(int j=0;j<4;j++) old+=v[x+dx[j]][y+dy[j]]; for(int j=0;j<4;j++){ int row=x+dx[j],col=y+dy[j]; if(v[row][col]!=' '&&v[row][col]!=d[i][j]){//判断是否合法 match=false; break; } } if(match){ for(int j=0;j<4;j++) v[x+dx[j]][y+dy[j]]=d[i][j]; dfs(nextx,nexty); for(int j=0;j<4;j++) v[x+dx[j]][y+dy[j]]=old[j]; }//回溯 } }上面这份代码是我的神仙老师
https://www.luogu.com.cn/user/333773满分算法
先给大家看几种合法的放置方法:
C.C CC. C.C ..C C.C ..C .C. CC. .C. CC. C.C ..C发现了吧,每一行或每一列的奶牛排列方式一定是交替排列的,而且上一行或上一列的交替排列方式对这一行或这一列交替排列方式没有影响,所以我们只需要先计算每一行的奇数列之和 和 偶数列之和 以及每一列的奇数行之和 和 偶数行之和(建议多读几遍,我当时都写晕了),再取每行的两种交替方式中的最大值,最后再取行上交替排列和列上交替排列的最大值就是答案了。
参考代码:
#include <bits/stdc++.h> using namespace std; int n,a,x[1010][2],y[1010][2],num,ans; int main(){ scanf("%d",&n); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) scanf("%d",&a),x[i][j%2]+=a,y[j][i%2]+=a; for(int i=1;i<=n;++i) num+=max(x[i][1],x[i][0]),ans+=max(y[i][1],y[i][0]); printf("%d",max(num,ans)); return 0; }//为什么大家的代码都这么长啊……
Update 1(2021/2/14):改正了50分算法的时间复杂度
- 1
信息
- ID
- 6439
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者