HLG 1214 方格取数
Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
设有N*N的方格图(N<=10),我们将其中的某些方格中填入正整数,而其他的方格中则放人数字0。如下图所示(见样例 ,黄色和蓝色分别为两次走的路线,其中绿色的格子为黄色和蓝色共同走过的):
某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B 点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字0)。此人从A点到B点共走两次,试找出2条这样的路径,使得取得的数之和为最大 。
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Input | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
有多组测试数据,每组格式如下: 第一行为一个整数N(表示N*N的方格图),接下来的每行有三个整数,前两个表示位置,第三个数为该位置上所放的数。一行单独的0表示输入结束。 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Output | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
与输入对应,有多组输出,每组只需输出一个整数,表示2条路径上取得的最大的和。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Sample Input | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
8 2 3 13 2 6 6 3 5 7 4 4 14 5 2 21 5 6 4 6 3 15 7 2 14 0 0 0 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Sample Output | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
67 |
CODE:
分析: 看成两个人同时从起点出发,保持第一个人始终在第二个人的左边。每种状态可以由三种状态转移而来。
View Code
#include<stdio.h> #include<string.h> #define max(a,b)(a)>(b)?(a):(b) int f[22][11][11]; int g[11][11]; int main() { int n,i,j,k,a,b,c,ans,res1,res2,res3,res4; while(scanf("%d",&n)!=EOF) { memset(g,0,sizeof(g)); memset(f,0,sizeof(f)); while(scanf("%d%d%d",&a,&b,&c),a&&b&&c) g[a][b]=c; for(k=1;k<n*2;k++) for(j=1;j<=k;j++) f[k][0][k-j+1]=g[j][k-j+1]; ans=0; for(k=2;k<2*n;k++) for(i=1;i<=k&&i<=n;i++) for(j=i+1;j<=k&&j<=n;j++) { res1=f[k-1][i][j-1]+g[k-i+1][i]+g[k-j+1][j]; res2=f[k-1][i-1][j]+g[k-i+1][i]+g[k-j+1][j]; res1=max(res1,res2); res3=f[k-1][i][j]+g[k-i+1][i]+g[k-j+1][j]; res1=max(res1,res3); res4=f[k-1][i-1][j-1]+g[k-i+1][i]+g[k-j+1][j]; res1=max(res1,res4); f[k][i][j]=res1; if(res1>ans) ans=res1; } if(n==1) printf("%d\n",g[1][1]); else printf("%d\n",ans); } return 0; }