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 }

 

posted @ 2012-06-15 21:00  Naix_x  阅读(206)  评论(0编辑  收藏  举报