「解题报告」P7301 【[USACO21JAN] Spaced Out S】
「解题报告」P7301 【[USACO21JAN] Spaced Out S】
神奇的5分算法:直接输出样例。
20分算法
直接把每个点是否有牛的状态DFS一遍同时判断是否合法,时间复杂度约为(因为有判断合法的剪枝所以会比这个低)。而在前四个测试点中,用枚举算法在最坏情况下需要运行次,时间非常富裕,但是在之后的测试点中就会超时了。
50分算法
每四个方格内都有种方法放置牛:
1 2 3 4 5 6
CC C. C. .C .C ..
.. C. .C C. .C CC
DFS每四个方格内的六种情况同时判断是否合法,时间复杂度约为(因为有判断合法的剪枝所以会比这个低)。
部分参考代码:
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];
}//回溯
}
}
上面这份代码是我的神仙老师 @akic 写的,大家可以去膜拜他
满分算法
先给大家看几种合法的放置方法:
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分算法的时间复杂度
本文作者:K8He
本文链接:https://www.cnblogs.com/K8He/p/P7301.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
标签:
解题报告
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步