hdu 2476 区间dp

题意:

给出两个串s1和s2,一次只能将一个区间刷一次,问最少几次能让s1=s2

例如zzzzzfzzzzz,长度为11,我们就将下标看做0~10

先将0~10刷一次,变成aaaaaaaaaaa

1~9刷一次,abbbbbbbbba

2~8:abcccccccba

3~7:abcdddddcba

4~6:abcdeeedcab

5:abcdefedcab

这样就6次,变成了s2串了

其 实如果a串是空串的话,我们可以写出这样的区间dp方程:设dp[i][j]表示从i到j至少要变多少次,则有dp[i][j]=min(dp[i+1] [j]+(b[i]==b[j]?0:1),dp[i+1][k]+dp[k+1][j](b[i]==b[k]))。

然后再考虑a串,设f[i]表示使a[0]~~a[i]==b[0]~~b[i]的最小步数,则有f[i]=min(f[j]+dp[j+1][i],dp[0][i],f[i-1](当a[i]==b[i]时)),即[j+1,i]可以看做一个空串。

 

 


if(b[i]==b[k])
     dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);

 

如果b[i]==b[k]  那么刷b[k]的时候一定会顺便刷上b[i] ,则可以少刷一次

 

 

2015-07-19:专题训练

 

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 #define MOD 1000000007
10 const int INF=0x3f3f3f3f;
11 const double eps=1e-5;
12 typedef long long ll;
13 #define cl(a) memset(a,0,sizeof(a))
14 #define ts printf("*****
");
15 const int MAXN=1005;
16 int n,m,tt;
17 char a[MAXN],b[MAXN];
18 int dp[MAXN][MAXN];
19 int ans[MAXN];
20 int main()
21 {
22     int i,j,k;
23     #ifndef ONLINE_JUDGE
24     freopen("1.in","r",stdin);
25     #endif
26     while(scanf("%s%s",a,b)!=EOF)
27     {
28         int len=strlen(a);
29         cl(dp);
30         for(i=0;i<len;i++)  dp[i][i]=1;
31         for(int d=1;d<len;d++)
32         {
33             for(i=0;i+d<len;i++)
34             {
35                 j=i+d;
36                 dp[i][j]=dp[i+1][j]+1;
37                 for(k=i+1;k<=j;k++)
38                 {
39                     if(b[k]==b[i])
40                         dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
41                 }
42             }
43         }
44         for(i=0;i<len;i++)
45         {
46             ans[i]=dp[0][i];
47         }
48         for(i=0;i<len;i++)
49         {
50             if(a[i]==b[i])
51             {
52                 if(i==0)    ans[i]=0;
53                 else ans[i]=ans[i-1];
54             }
55             else
56             {
57                 for(j=0;j<i;j++)
58                 {
59                     ans[i]=min(ans[i],ans[j]+dp[j+1][i]);
60                 }
61             }
62         }
63         printf("%d
",ans[len-1]);
64     }
65 }
View Code

 

 

 2015-05-10:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 #define MOD 1000000007
10 const int INF=0x3f3f3f3f;
11 const double eps=1e-5;
12 typedef long long ll;
13 #define cl(a) memset(a,0,sizeof(a))
14 #define ts printf("*****
");
15 const int MAXN=1005;
16 int n,m,tt;
17 char a[MAXN],b[MAXN];
18 int dp[MAXN][MAXN];
19 int ans[MAXN];
20 int main()
21 {
22     int i,j,k;
23     #ifndef ONLINE_JUDGE
24     freopen("1.in","r",stdin);
25     #endif
26     while(scanf("%s%s",a,b)!=EOF)
27     {
28         int n=strlen(a);
29         cl(dp);
30         for(i=0;i<n;i++)    dp[i][i]=1;
31         for(int len=1;len<n;len++)
32         {
33             for(i=0;i+len<=n;i++)
34             {
35                 j=i+len;
36                 dp[i][j]=dp[i+1][j]+1;
37                 for(k=i+1;k<=j;k++)
38                 {
39                     if(b[i]==b[k])
40                         dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
41                 }
42             }
43         }
44         for(i=0;i<n;i++)
45         {
46             ans[i]=dp[0][i];
47         }
48         for(i=0;i<n;i++)
49         {
50             if(a[i]==b[i])
51             {
52                 if(i==0)    ans[i]=0;
53                 else ans[i]=ans[i-1];
54             }
55             else
56             {
57                 for(j=0;j<i;j++)
58                 {
59                     ans[i]=min(ans[i],ans[j]+dp[j+1][i]);
60                 }
61             }
62         }
63         printf("%d
",ans[n-1]);
64     }
65 }
原文地址:https://www.cnblogs.com/cnblogs321114287/p/4269890.html