题意:
给你一个字符串,做为被查字符串。
然后给你一系列的字符串,作为字典。
然你从被查字符串中去除掉字典中含有的字符串,可以是不连续的~~
求:被查字符串最小剩下多少个字符。
做法:
dp[i]代表第i字符后面的字符去除掉字典后剩下几个字符。
dp[i]=min(dp[i],dp[i+1]+1,dp[k+1]+k+1-i-lens);
k代表从第i个字符,往后走,可以找到的一个字典中有的字符串的结束。
lens代表这个字符串的长度。
注意:
dp题目无注意,找好状态方程就好了。
还是有一点需要注意,i后面有可能有好多字符串,所以每比较出来一个字符串,都要min一下。
#include<iostream> #include<stdio.h> #include<string.h> #define MAXS 999999 using namespace std; int min(int a,int b,int c) { // printf("%d %d %d\n",a,b,c); int d=a; if(a>b) d=b; if(d>c) d=c; return d; } int main() { int w,l,i,j,k; char str[1001]; char dian[601][30]; cin>>w>>l; getchar(); gets(str); for(i=0;i<w;i++) { gets(dian[i]); } int dp[301]; for(i=0;i<301;i++) { dp[i]=MAXS; } int lens; dp[l]=0; int x2=0; for(i=l-1;i>=0;i--) { for(j=0;j<w;j++) { dp[i]=min(dp[i],MAXS,dp[i+1]+1); if(dian[j][0]!=str[i])continue; lens=strlen(dian[j]); x2=0; for(k=i;k<l;k++) { if(dian[j][x2]==str[k]) { x2++; } if(x2==lens)break; } if(k!=l) { dp[i]=min(dp[i],dp[i+1]+1,dp[k+1]+k+1-i-lens); } } //printf("%d %d,%d %d %d\n",j,w,i,k,lens); // printf("dp[%d]=%d\n",i,dp[i]); } printf("%d\n",dp[0]); return 0; }