• 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
    ",str[0]-'0');
     20             else
     21             printf("0
    ");
     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("
    ");
    106     }
    107     return 0;
    108 }
  • 相关阅读:
    2.25家庭记账本小软件
    2.10简单体温记录小软件总结
    4.26PHP
    4.25Android
    4.24css
    4.23css
    4.22电梯演讲
    4.21python
    4.20python
    4.19python
  • 原文地址:https://www.cnblogs.com/naix-x/p/3176552.html
Copyright © 2020-2023  润新知