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 }
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 }