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 }

 

 

你可能感兴趣的:(git)