POJ 2948 Martian Mining(DP)这是POJ第200道,居然没发现
两种矿石,Y和B,Y只能从从右到左,B是从下到上,每个空格只能是上下或者左右,具体看图。求左端+上端最大值。
很容易发现如果想最优,分界线一定是不下降的,分界线上面全是往上,分界线下面都是往左,然后就发现每一行,只和上一行有关系,DP可搞。
应该可以单调队列优化,我直接暴力水过了。。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 int dp[501][501]; 8 int sum1[501][501]; 9 int sum2[501][501]; 10 int p1[501][501]; 11 int p2[501][501]; 12 int main() 13 { 14 int n,m,i,j,k,ans; 15 while(scanf("%d%d",&n,&m)!=EOF) 16 { 17 if(n == 0&&m == 0) break; 18 memset(dp,0,sizeof(dp)); 19 for(i = 1;i <= n;i ++) 20 { 21 for(j = 1;j <= m;j ++) 22 scanf("%d",&p1[i][j]); 23 } 24 for(i = 1;i <= n;i ++) 25 { 26 for(j = 1;j <= m;j ++) 27 scanf("%d",&p2[i][j]); 28 } 29 for(i = 1;i <= n;i ++) 30 { 31 for(j = 1;j <= m;j ++) 32 { 33 sum1[i][j] = sum1[i][j-1] + p1[i][j]; 34 sum2[i][j] = sum2[i][j-1] + p2[i][j]; 35 } 36 } 37 for(i = 1;i <= n;i ++) 38 { 39 for(j = 0;j <= m;j ++) 40 { 41 for(k = 0;k <= j;k ++) 42 { 43 dp[i][j] = max(dp[i][j],dp[i-1][k]+sum1[i][j]+sum2[i][m]-sum2[i][j]); 44 } 45 } 46 } 47 ans = 0; 48 for(i = 0;i <= m;i ++) 49 ans = max(ans,dp[n][i]); 50 printf("%d\n",ans); 51 } 52 return 0; 53 }