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("*****\n");

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\n",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("*****\n");

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\n",ans[n-1]);

64     }

65 }

 

你可能感兴趣的:(HDU)