Codeforces 803E--Roma and Poker (DP)

原题链接:http://codeforces.com/problemset/problem/803/E

题意:给一个n长度的字符串,其中'?'可以替换成'D'、'W'、'L'中的任意一种,'D'等价于0, 'W'等价于1、'L'等价于-1。输出所有'?'被替换掉后,W和L的数目之差为k,且任意一个[1, i]的子串中W和L数目之差不能等于k。

思路:用DP做。定义bool dp[i][j]代表前i个字符W和L数目之差为j, -k<=j<=k(在数组中范围为[0, 2*k]),那么当str[i]为'D'时dp[i][j]转移到dp[i-1][j], 为'W'时dp[i][j]转移到dp[i-1][j+1], str[i]为'D'时dp[i][j]转移到dp[i-1][j-1], 初始值dp[0][0]为true。

接着用一遍dfs倒推求结果,注意字符加的位置。

AC代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<string>
 5 using namespace std;
 6 int dp[2005][4005];
 7 int n,k;
 8 string str;
 9 void change(int i, int L, int D, int W){
10         for(int j=1;j<2*k;j++){
11             if(dp[i-1][j]){
12                 if(D) dp[i][j]=1;
13                 if(L){
14                     if(i!=n&&j-1==0)//[1, i]子串中W和L数目之差不能等于k
15                         continue;
16                     dp[i][j-1]=1;
17                 } 
18                 if(W){
19                     if(i!=n&&j+1==2*k)
20                         continue;
21                     dp[i][j+1]=1;    
22                 }
23         }
24     }
25     return;
26 }
27 string ss;
28 //int t=0;
29 bool res(int i, int j, string ans){
30     //t++;
31     if(i==0&&j==k){
32         ss=ans;
33         return 1;
34     }
35     if(str[i-1]!='?'){
36         if(str[i-1]=='D') return res(i-1, j, 'D'+ans);
37         if(str[i-1]=='W') return res(i-1, j-1, 'W'+ans);
38         if(str[i-1]=='L') return res(i-1, j+1, 'L'+ans);
39     }
40     else
41     {
42         if(dp[i-1][j]&&res(i-1, j, 'D'+ans)) return 1;
43         if(dp[i-1][j-1]&&res(i-1, j-1, 'W'+ans)) return 1;
44         if(dp[i-1][j+1]&&res(i-1, j+1, 'L'+ans)) return 1;
45     }
46     
47     return 0;
48 }
49 int main()
50 {
51     while(cin>>n>>k)
52     {
53         memset(dp, 0, sizeof(dp));
54         dp[0][k]=1;
55         cin>>str;
56         if(str[n-1]=='D'){
57             cout<<"NO"<<endl;
58             continue;
59         }
60         for(int i=1;i<=n;i++){
61             if(str[i-1]=='?')
62                 change(i, 1, 1, 1);
63             else if(str[i-1]=='D')
64                 change(i, 0, 1, 0);    
65             else if(str[i-1]=='W')
66                 change(i, 0, 0, 1);
67             else
68                 change(i, 1, 0, 0);
69         }
70         string ans;
71         if(dp[n][0]){
72             res(n, 0, ans);
73             cout<<ss<<endl; 
74         }
75         else if(dp[n][2*k]){
76             res(n, 2*k, ans);
77             cout<<ss<<endl;
78         }
79         else
80             cout<<"NO"<<endl;
81         //cout<<t<<endl;
82     }
83     return 0;
84 }

这代码调了我好久啊QAQ,感觉自己真菜

 

原文地址:https://www.cnblogs.com/MasterSpark/p/7450853.html