hdu 4433

一道dp题,虽然知道是dp,但是不会做;

学习了ACM_cxlove大神的代码,终于明白了;

搬运工:

dp[i][j][k]表示 前i个已经完全匹配,而这时候,第i+1个已经加了j位,第i+2位已经加了k

转移分为两步,枚举加,枚举减;

上面是大神的原话,不过看了好久的代码才明白;

下面是我的一点领悟:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define inf 1<<20
 5 #define N 1005
 6 using namespace std;
 7 char s1[N],s2[N];
 8 int dp[N][10][10];
 9 int main()
10 {
11     while(scanf("%s%s",s1,s2)!=EOF)
12     {
13         int l=strlen(s1);
14         for(int i=0; i<=l; i++) for(int j=0; j<10; j++) for(int k=0; k<10; k++) dp[i][j][k]=inf;
15         dp[0][0][0]=0;
16         for(int i=0; i<l; i++)//表示要排到了第i位;
17             for(int j=0; j<10; j++)//第i位移动的数量;
18                 for(int k=0; k<10; k++)//第i+1位移动的数量;
19                 {
20                     int t=(s2[i]-s1[i]-j+20)%10;//枚举向上移动的数目;
21                     for(int a=0; a<=t; a++)//第i+1移动的数目;
22                         for(int b=0; b<=a; b++)//第i+2位移动的数目;
23                             dp[i+1][(k+a)%10][b]=min(dp[i+1][(k+a)%10][b],dp[i][j][k]+t);//排好第i位的状态转移到i+1位;
24                     t=10-t;//枚举向下移动的数目;
25                     for(int a=0; a<=t; a++)
26                         for(int b=0; b<=a; b++)
27                             dp[i+1][(k-a+10)%10][(10-b)%10]=min(dp[i+1][(k-a+10)%10][(10-b)%10],dp[i][j][k]+t);
28                 }
29         printf("%d\n",dp[l][0][0]);
30     }
31     return 0;
32 }
View Code

 

 

posted @ 2013-09-25 17:03  Yours1103  阅读(187)  评论(0编辑  收藏  举报