您的位置:首页 > 其它

Codeforces 803E Roma and Poker【Dp+记录路径】

2017-05-01 16:22 411 查看
E. Roma and Poker

time limit per test
2 seconds

memory limit per test
256 megabytes

input
standard input

output
standard output

Each evening Roma plays online poker on his favourite website. The rules of poker on this website are a bit strange: there are always two players in a hand, there are no bets, and the winner takes
1 virtual bourle from the loser.

Last evening Roma started to play poker. He decided to spend no more than
k virtual bourles — he will stop immediately if the number of his loses exceeds the number of his wins by
k. Also Roma will leave the game if he wins enough money for the evening, i.e. if the number of wins exceeds the number of loses by
k.

Next morning Roma found a piece of paper with a sequence on it representing his results. Roma doesn't remember the results exactly, and some characters in the sequence are written in a way such that it's impossible to recognize this character, so Roma can't
recall whether he won k bourles or he lost.

The sequence written by Roma is a string s consisting of characters
W (Roma won the corresponding hand),
L (Roma lost), D (draw) and
? (unknown result). Roma wants to restore any
valid sequence by changing all ? characters to
W, L or
D. The sequence is called
valid if all these conditions are met:

In the end the absolute difference between the number of wins and loses is equal to
k;
There is no hand such that the absolute difference before this hand was equal to
k.
Help Roma to restore any such sequence.

Input
The first line contains two numbers n (the length of Roma's sequence) and
k (1 ≤ n, k ≤ 1000).

The second line contains the sequence s consisting of characters
W, L,
D and ?. There are exactly
n characters in this sequence.

Output
If there is no valid sequence that can be obtained from
s by replacing all
? characters by W,
L or D, print
NO.

Otherwise print this sequence. If there are multiple answers, print any of them.

Examples

Input
3 2
L??


Output
LDL


Input
3 1
W??


Output
NO


Input
20 5
?LLLLLWWWWW?????????


Output
WLLLLLWWWWWWWWLWLWDW


题目大意:

给你一个长度为N的字符串,其中包含四种字符:L,D,W,?.其中L表示罗马队输了,D代表平,W代表赢了,?表示不确定。

?可以填充为L,D,W任意一个。

现在要求找到一个合法的情况使得满足以下两个条件:

①在结尾的时候,Abs(L的数量-W的数量)==k

②在结尾之前,Abs(L的数量-W的数量)不能有等于k的时候。

思路:

1、当前位子的?设定为某一种情况会影响之后的设定方案,但是不会影响之前的设定方案,那么无后效性的一个问题,我们首先考虑dp.

设定dp【i】【j】表示到位子i,W比L多的个数为j(j可能为负,表示L比W多的个数为-j)个的情况是否存在。

因为数组范围界定条件有限,所以我们开数组为dp【1005】【5005】即可,设定mid==2500.也就是表示0的位子,那么2499就表示dp【i】【-1】;

2、接下来考虑状态转移方程:

①a【i】==‘L’:dp【i】【j】=dp【i-1】【j+1】;

②a【i】==‘W’:dp【i】【j】=dp【i-1】【j-1】;

③a【i】==‘D’:dp【i】【j】=dp【i-1】【j】;

④a【i】==‘?’:dp【i】【j】=max(dp【i-1】【j+1】,dp【i-1】【j-1】,dp【i-1】【j】);

初始化dp【0】【0】=1;

3、接下来逆向维护一条可行路径出来即可。

注意不满足条件的情况一定不能走,稍微注意点细节就行了。

Ac代码:

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int dp[1005][5005];
char a[1005];
char ans[1005];
int main()
{
int mid=2502;
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(ans,' ',sizeof(ans));
memset(dp,0,sizeof(dp));
scanf("%s",a+1);
dp[0][mid]=1;
for(int i=1; i<=n; i++)
{
for(int j=mid-m; j<=mid+m; j++)
{
if(i!=n)
{
if(j==mid-m||j==mid+m)continue;
}
if(a[i]=='W')dp[i][j]=dp[i-1][j-1];
if(a[i]=='L')dp[i][j]=dp[i-1][j+1];
if(a[i]=='D')dp[i][j]=dp[i-1][j];
if(a[i]=='?')
{
dp[i][j]=max(dp[i][j],dp[i-1][j-1]);
dp[i][j]=max(dp[i][j],dp[i-1][j+1]);
dp[i][j]=max(dp[i][j],dp[i-1][j]);
}
}
}
if(dp
[mid+m]==0&&dp
[mid-m]==0)
{
printf("NO\n");
return 0;
}
if(dp
[mid+m]==1)
{
int flag=0;
int tmp=mid+m;
for(int i=n; i>=1; i--)
{
if(a[i]!='?')
{
if(a[i]=='W')tmp--;
if(a[i]=='L')tmp++;
if(tmp==mid+m||tmp==mid-m)flag=1;
ans[i]=a[i];
}
else
{
if(tmp!=mid+m&&tmp!=mid-m&&dp[i-1][tmp]==1)ans[i]='D';
else if(tmp+1<mid+m&&dp[i-1][tmp+1]==1)ans[i]='L',tmp=tmp+1;
else if(tmp-1>mid-m&&dp[i-1][tmp-1]==1)ans[i]='W',tmp=tmp-1;
else flag=1;
}
}
if(flag==0)
{
for(int i=1; i<=n; i++)printf("%c",ans[i]);
printf("\n");
return 0;
}
}
if(dp
[mid-m]==1)
{
int flag=0;
int tmp=mid-m;
for(int i=n; i>=1; i--)
{
if(a[i]!='?')
{
if(a[i]=='W')tmp--;
if(a[i]=='L')tmp++;
if(tmp==mid+m||tmp==mid-m)flag=1;
ans[i]=a[i];
}
else
{
if(tmp!=mid+m&&tmp!=mid-m&&dp[i-1][tmp]==1)ans[i]='D';
else if(tmp+1<mid+m&&dp[i-1][tmp+1]==1)ans[i]='L',tmp=tmp+1;
else if(tmp-1>mid-m&&dp[i-1][tmp-1]==1)ans[i]='W',tmp=tmp-1;
else flag=1;
}
}
if(flag==0)
{
for(int i=1; i<=n; i++)printf("%c",ans[i]);
printf("\n");
return 0;
}
else printf("NO\n");
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Codeforces 803E