1、poj 3267
题意:给你一个字符串,下面有若干单词,问字符串要变成由下面单词组成的字符串,至少要删除多少个字母......
例如:
6 10 browndcodw cow milk white black brown farmer
其中,brown和cow可以组成browncow,这样至少是删除两个字母.......当然,下面的单词可以重复利用......
思路:dp[i]表示历遍到第i个字符时要删除的最少字母数,那么从后面往前面历遍,dp[i]=dp[i+1]+1
若是在i~~lens中,可以找到某个字符串,并且首字母就是i所处位置的字符,那么动态转移dp[i]=min(dp[i],dp[pos]+lens-i-lent);
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 using namespace std; 5 int dp[1000]; 6 char s[1000],t[605][30]; 7 int main() 8 { 9 int lens,m; 10 while(scanf("%d%d",&m,&lens)>0) 11 { 12 scanf("%s",s); 13 for(int i=0;i<m;i++) 14 scanf("%s",t[i]); 15 dp[lens]=0; 16 for(int i=lens-1;i>=0;i--) 17 { 18 dp[i]=dp[i+1]+1; 19 int lent; 20 for(int j=0;j<m;j++) 21 { 22 lent=strlen(t[j]); 23 int p=0,p1=i; 24 if(s[i]==t[j][0]) 25 while(p<lent&&p1<lens) 26 { 27 if(s[p1]==t[j][p]) 28 { 29 p1++; 30 p++; 31 } 32 else 33 p1++; 34 } 35 if(p==lent) 36 { 37 dp[i]=min(dp[i],dp[p1]+p1-i-lent); 38 } 39 } 40 } 41 printf("%d\n",dp[0]); 42 } 43 return 0; 44 }