URAL 1029. Ministry(DP)
好久没刷DP了,很没状态啊。这个题,先是算法想错,以为是类似滑雪的那种记忆化DP,结果变出来,没有终止条件,死循环。。。后来换了算法O(n^3) 这个状态方程很容易就能看出来,主要是实现的问题。。。还真不好说,这个是怎么做的,就是一直找左右,直到没法更新为止吧。最郁闷的是傻的不知道10的9次方会爆int,写完后URAL给的错误看不太懂,以为是数组越界。。。。。最近1Y很困难啊。。。
1 #include <stdio.h> 2 #include <string.h> 3 #define N 10000000000 4 long long dp[111][511],p[111][511],o[100000]; 5 int main() 6 { 7 long long m,n,i,j,k,z,min = N,num; 8 scanf("%lld%lld",&m,&n); 9 for(i = 1; i <= m; i ++) 10 for(j = 1; j <= n; j ++) 11 { 12 scanf("%lld",&p[i][j]); 13 if(i == 1) 14 dp[i][j] = p[i][j]; 15 } 16 for(i = 2; i <= m; i ++) 17 for(j = 1;; j ++) 18 { 19 z = 1; 20 for(k = 1; k <= n;k ++) 21 { 22 if(j == 1) 23 { 24 dp[i][k] = dp[i-1][k] + p[i][k]; 25 z = 0; 26 } 27 else 28 { 29 if(dp[i][k] > dp[i][k-1]+p[i][k]&&k-1>=1) 30 { 31 z = 0; 32 dp[i][k] = dp[i][k-1]+p[i][k]; 33 } 34 if(dp[i][k] > dp[i][k+1]+p[i][k]&&k+1<=n) 35 { 36 z = 0; 37 dp[i][k] = dp[i][k+1]+p[i][k]; 38 } 39 } 40 } 41 if(z) break; 42 } 43 for(i = 1;i <= n;i ++) 44 { 45 if(min > dp[m][i]) 46 { 47 min = dp[m][i]; 48 j = i; 49 k = m; 50 } 51 } 52 num = 1; 53 o[num] = j; 54 num ++; 55 while(k > 1) 56 { 57 if(min == dp[k-1][j] + p[k][j]) 58 { 59 min -= p[k][j]; 60 k = k - 1; 61 o[num] = j; 62 num ++; 63 } 64 else if(min == dp[k][j-1]+p[k][j]&&j-1 >= 1) 65 { 66 min -= p[k][j]; 67 j = j - 1; 68 o[num] = j; 69 num ++; 70 } 71 else if(min == dp[k][j+1]+p[k][j]&&j+1 <= n) 72 { 73 min -= p[k][j]; 74 j = j + 1; 75 o[num] = j; 76 num ++; 77 } 78 } 79 for(i = num-1;i >= 1;i --) 80 { 81 if(i != 1) 82 printf("%lld ",o[i]); 83 else 84 printf("%lld\n",o[i]); 85 } 86 return 0; 87 }