POJ 3373 Changing Digits(DP)

题目链接 

记录路径的DP,看的别人的思路。自己写的也不好,时间居然2000+,中间的取余可以打个表,优化一下。

写的各种错,导致wa很多次,写了一下午,自己构造数据,终于发现了最后一个bug。

dp[i][j]表示前i位取余得到j,需要最少改变多少位。

这样可以得到最少改变多少位了,但是,还要保证,最小。学习别人的题解,开一个标记数组,先从后倒回来,把这些可以达到最小的路径都记录下来。

然后再从头找最小的那一条路径。这样就能保证,最小了。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 using namespace std;
  5 #define INF 100000000
  6 int dp[101][10001];
  7 bool o[101][10001];
  8 int que[101];
  9 int main()
 10 {
 11     int i,j,k,n,m,t,z,pos;
 12     char str[101];
 13     while(scanf("%s%d",str,&m)!=EOF)
 14     {
 15         n = strlen(str);
 16         if(n == 1)
 17         {
 18             if((str[0]-'0')%m == 0)
 19             printf("%d\n",str[0]-'0');
 20             else
 21             printf("0\n");
 22             continue;
 23         }
 24         for(i = 0; i < n; i ++)
 25         {
 26             for(j = 0; j < m; j ++)
 27             {
 28                 dp[i][j] = INF;
 29                 o[i][j] = 0;
 30             }
 31         }
 32         for(i = 1; i < 10; i ++)
 33         {
 34             t = i%m;
 35             if(i == str[0]-'0')
 36                 z = 0;
 37             else
 38                 z = 1;
 39             dp[0][t] = min(dp[0][t],z);
 40         }
 41         for(i = 0; i < n-1; i ++)
 42         {
 43             for(j = 0; j < m; j ++)
 44             {
 45                 if(dp[i][j] == INF) continue;
 46                 for(k = 0; k < 10; k ++)
 47                 {
 48                     if(k == str[i+1]-'0')
 49                         z = 0;
 50                     else
 51                         z = 1;
 52                     dp[i+1][(j*10+k)%m] = min(dp[i+1][(j*10+k)%m],dp[i][j]+z);
 53                 }
 54             }
 55         }
 56         o[n-1][0] = 1;
 57         for(i = n-2; i >= 0; i --)
 58         {
 59             for(j = 0; j < m; j ++)
 60             {
 61                 if(dp[i][j] == INF) continue;
 62                 for(k = 0; k < 10; k ++)
 63                 {
 64                     if(k == str[i+1]-'0')
 65                         z = 0;
 66                     else
 67                         z = 1;
 68                     if(dp[i+1][(j*10+k)%m] == dp[i][j]+z&&o[i+1][(j*10+k)%m])
 69                     {
 70                         o[i][j] = 1;
 71                     }
 72                 }
 73             }
 74         }
 75         for(i = 1; i < 10; i ++)
 76         {
 77             t = i%m;
 78             if(i == str[0]-'0')
 79                 z = 0;
 80             else
 81                 z = 1;
 82             if(o[0][t]&&dp[0][t] == z)
 83             {
 84                 printf("%d",i);
 85                 pos = t;
 86                 break;
 87             }
 88         }
 89         for(i = 1;i < n;i ++)
 90         {
 91             for(j = 0;j < 10;j ++)
 92             {
 93                 if(j == str[i]-'0')
 94                     z = 0;
 95                 else
 96                     z = 1;
 97                 if(o[i][(pos*10+j)%m]&&dp[i][(pos*10+j)%m] == dp[i-1][pos]+z)
 98                 {
 99                     printf("%d",j);
100                     pos = (pos*10+j)%m;
101                     break;
102                 }
103             }
104         }
105         printf("\n");
106     }
107     return 0;
108 }

 

 

posted @ 2013-07-07 17:19  Naix_x  阅读(292)  评论(0编辑  收藏  举报