【NOIP2009】道路游戏
题面
https://www.luogu.org/problem/P1070
题解
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,p,ans=0; int a[1050][1050],sum[1050][1050],oto[1050][1050],f[1050],cost[1050]; void suc(int &x){ if (x==n) x=1; else x++; } int dfs(int x,int colled){ if (x==m+1) { if (colled>ans) ans=colled; return 0; } if (f[x]!=-1) { if (colled+f[x]>ans) ans=colled+f[x]; return f[x]; } int i,j,ans0=0,t0; for (i=1;i<=n;i++) for (j=x;j<=min(x+p-1,m);j++) { t0=dfs(j+1,colled-cost[oto[i][x]]+sum[i][j]-sum[i][x-1]); ans0=max(ans0,-cost[oto[i][x]]+sum[i][j]-sum[i][x-1]+t0); } if (colled+ans0>ans) ans=colled+ans0; f[x]=ans0; return f[x]; } int main() { int x,y,i,j; scanf("%d %d %d",&n,&m,&p); for (i=1;i<=n;i++) for (j=1;j<=m;j++) scanf("%d",&a[i][j]); for (i=1;i<=n;i++) { x=i; y=1; for (j=1;j<=m;j++) { sum[i][j]=sum[i][j-1]+a[x][y]; oto[i][j]=x; suc(x); y++; } } for (i=1;i<=n;i++) scanf("%d",&cost[i]); memset(f,-1,sizeof(f)); dfs(1,0); printf("%d\n",ans); }