• 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,感觉自己真菜

     

  • 相关阅读:
    android 通知栏 notifcation
    通过ResultSet获取到rs的记录数的几种方法
    网上书城随笔
    jdbc 事务
    正则表达式
    String,StringBuffer与StringBuilder的区别??
    Java 之 FileReader FileInputStream InputStreamReader BufferedReader 作用与区
    算法
    呵呵
    Hibernate
  • 原文地址:https://www.cnblogs.com/MasterSpark/p/7450853.html
Copyright © 2020-2023  润新知