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 }

 

你可能感兴趣的:(ini)