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
",cse);
41         else if(good) printf("Case %d: GOOD
",cse);
42         else printf("Case %d: BAD
",cse);
43     }
44     return 0;
45 }
原文地址:https://www.cnblogs.com/WABoss/p/5133565.html