LightOJ1051 Good or Bad(DP)
这题感觉做法应该挺多吧,数据规模那么小。
我用DP乱搞了。。
dp0[i][j]表示字符串前i位能否组成末尾有连续j个元音字母
dp1[i][j]表示字符串前i位能否组成末尾有连续j个辅音字母
- 我的转移方案是尽量不要出现BAD字符串。
- 如果最后转移不过去那就说明一定会出现BAD字符串,如果可以转移到最后那就说明字符串可以出现GOOD的情况。
- 另外,在转移过程中可以顺便得出字符串能不能出现BAD的情况。
转移写起来还挺棘手的。。
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 bool vow(char ch){ 5 return ch=='A'||ch=='E'||ch=='I'||ch=='O'||ch=='U'; 6 } 7 bool d[2][55][6]; 8 int main(){ 9 char str[55]; 10 int t; 11 scanf("%d",&t); 12 for(int cse=1; cse<=t; ++cse){ 13 scanf("%s",str+1); 14 int n=strlen(str+1); 15 memset(d,0,sizeof(d)); 16 d[0][0][0]=d[1][0][0]=1; 17 bool bad=0; 18 for(int i=1; i<=n; ++i){ 19 if(str[i]=='?' || vow(str[i])){ 20 for(int j=0; j<=1; ++j){ 21 if(d[1][i-1][j]){ 22 d[1][i][j+1]=1; 23 d[0][i][0]=1; 24 } 25 } 26 if(d[1][i-1][2]) bad=1; 27 } 28 if(str[i]=='?' || !vow(str[i])){ 29 for(int j=0; j<=3; ++j){ 30 if(d[0][i-1][j]){ 31 d[0][i][j+1]=1; 32 d[1][i][0]=1; 33 } 34 } 35 if(d[0][i-1][4]) bad=1; 36 } 37 } 38 bool good=0; 39 for(int i=0;i<6;++i) good|=(d[0][n][i]|d[1][n][i]); 40 if(good && bad) printf("Case %d: MIXED\n",cse); 41 else if(good) printf("Case %d: GOOD\n",cse); 42 else printf("Case %d: BAD\n",cse); 43 } 44 return 0; 45 }