2021“MINIEYE杯”中国大学生算法设计超级联赛(3)
1009:Rise in Price
思路:
dalao超详细思路传送门
直接爆搜 dfs 遍历 每条 路径 (必然超时) 考虑剪枝 思路如下:
代码:
#include<iostream>
#include<algorithm>
using namespace std;
const long long N=105;
long long ans,n;
long long a[N][N],b[N][N],c[N][N];
long long get(long long sa,long long sb,long long cm){
return (sa+sb+cm)/2;
}
void dfs(long long x,long long y,long long sa,long long sb){
if(x==n&&y==n){
ans=max(ans,sa*sb);
return ;
}
long long t;
t=get(sa,sb,c[x+1][y]);
if(x<n&&t*t>ans)
dfs(x+1,y,sa+a[x+1][y],sb+b[x+1][y]);
t=get(sa,sb,c[x][y+1]);
if(y<n&&t*t>ans)
dfs(x,y+1,sa+a[x][y+1],sb+b[x][y+1]);
}
int main(){
int T;
cin>>T;
while(T--){
scanf("%lld",&n);
for(long long i=1;i<=n;i++)
for(long long j=1;j<=n;j++)
scanf("%lld",&a[i][j]);
for(long long i=1;i<=n;i++)
for(long long j=1;j<=n;j++)
scanf("%lld",&b[i][j]);
for(long long i=n;i>=1;i--){
for(long long j=n;j>=1;j--){
c[i][j]=a[i][j]+b[i][j];
if(i<n)
c[i][j]=max(c[i][j],c[i+1][j]+a[i][j]+b[i][j]);
if(j<n)
c[i][j]=max(c[i][j],c[i][j+1]+a[i][j]+b[i][j]);
}
}
ans=0;
dfs(1,1,a[1][1],b[1][1]);
cout<<ans<<endl;
}
return 0;
}