HDU 2686 多线程DP
http://acm.hdu.edu.cn/showproblem.php?pid=2686
和传纸条的题一个类型,起点和终点重合,其余都不重合
dp[k,x1,y1,x2,y1)=Max(dp[k-1,x1-1,y1,x2-1,y2],
dp[k-1,x1-1,y1,x2,y2-1],
dp[k-1,x1,y1-1,x2-1,y2],
dp[k-1,x1,y1-1,x2,y2-1]+map[x1][y1]+map[x2][y2];
因为x1+y1=k,所以压缩成三维
dp[k][i][j]=Max(dp[k-1][i-1][j-1],dp[k-1][i][j],dp[k-1][i-1][j],dp[k-1][i][j-1])+map[i][k-i]+map[j][k-j];
代码:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #define MMax(a,b)a>b?a:b using namespace std; int dp[65][32][32]; int map[32][32]; int Max(int a,int b,int c,int d) { a=MMax(a,b); c=MMax(c,d); a=MMax(a,c); return a; } int main() { int n; int i,j,k; while(~scanf("%d",&n)) { for(i=0;i<n;i++) for(j=0;j<n;j++) scanf("%d",&map[i][j]); memset(dp,0,sizeof(dp)); for(k=1;k<=2*n-3;k++) { for(i=0;i<=k;i++) for(j=0;j<=k;j++) { if(i>=n||j>=n)continue; if(i==j)continue; dp[k][i][j]=Max(dp[k-1][i-1][j-1],dp[k-1][i][j], dp[k-1][i-1][j],dp[k-1][i][j-1])+map[i][k-i]+map[j][k-j]; } } dp[2*n-2][n-1][n-1]=Max(dp[2*n-3][n-1][n-2],dp[2*n-3][n-2][n-1])+map[n-1][n-1]; printf("%d\n",dp[2*n-2][n-1][n-1]+map[0][0]); } return 0; }