Codeforces Round #472 _A

A. Tritonic Iridescence

Overlooking the captivating blend of myriads of vernal hues, Arkady the painter lays out a long, long canvas.

Arkady has a sufficiently large amount of paint of three colours: cyan, magenta, and yellow. On the one-dimensional canvas split into n consecutive segments, each segment needs to be painted in one of the colours.

Arkady has already painted some (possibly none or all) segments and passes the paintbrush to you. You are to determine whether there are at least two ways of colouring all the unpainted segments so that no two adjacent segments are of the same colour. Two ways are considered different if and only if a segment is painted in different colours in them.

Input
The first line contains a single positive integer n (1 ≤ n ≤ 100) — the length of the canvas.

The second line contains a string s of n characters, the i-th of which is either ‘C’ (denoting a segment painted in cyan), ‘M’ (denoting one painted in magenta), ‘Y’ (one painted in yellow), or ‘?’ (an unpainted one).

Output
If there are at least two different ways of painting, output “Yes”; otherwise output “No” (both without quotes).

You can print each character in any case (upper or lower).

Examples
inputCopy
5
CY??Y
output
Yes
inputCopy
5
C?C?Y
output
Yes
inputCopy
5
?CYC?
output
Yes
inputCopy
5
C??MM
output
No
inputCopy
3
MMY
output
No
Note
For the first example, there are exactly two different ways of colouring: CYCMY and CYMCY.

For the second example, there are also exactly two different ways of colouring: CMCMY and CYCMY.

For the third example, there are four ways of colouring: MCYCM, MCYCY, YCYCM, and YCYCY.

For the fourth example, no matter how the unpainted segments are coloured, the existing magenta segments will prevent the painting from satisfying the requirements. The similar is true for the fifth example.

题意:染色问题->给个字符串,仅包含Y,C , M , ?,四个字符
Y C M 分别代表3种颜色,‘?’可以染色为Y C M中,任一一种颜色
要求相邻两个字符不能为相同颜色,判断给定字符串是否能染色成功,并且存在两种以上的染色方案

思路:可以很好的发现染色方案存在递推关系:

dp[i][j]表示长度为i,以j字符结尾的染色方案数,
令:
0为颜色Y
1为颜色C
2为颜色M

那么:dp[i][0]=dp[i-1][1]+dp[i-1][2]
dp[i][1]=dp[i-1][0]+dp[i-1][2]
dp[i][2]=dp[i-1][0]+dp[i-1][1]
这样一个字符串的染色方案数量就可以直接计算出来的
但是!!!
有个trick,就是染色方案很大,爆long long,所以当dp[i][j]大于2时,让dp[i][j]=2即可

代码:

#include
#include
using namespace std;
typedef long long ll;
ll dp[1005][3];
char str[1005];//c,y,m

int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>str[i];


    if(str[1]=='?'){
            dp[1][0]=1;
            dp[1][1]=1;
            dp[1][2]=1;
        }
        else{
            if(str[1]=='C'){
                dp[1][0]=1;
            }
            else if(str[1]=='Y'){
                    dp[1][1]=1;
            }
            else{
                dp[1][2]=1;
            }
        }
    for(int i=2;i<=n;i++){
        if(str[i]=='?'){
            dp[i][0]=dp[i-1][1]+dp[i-1][2];
            dp[i][1]=dp[i-1][0]+dp[i-1][2];
            dp[i][2]=dp[i-1][0]+dp[i-1][1];

        }
        else{
            if(str[i]=='C'){
                dp[i][0]=dp[i-1][1]+dp[i-1][2];

            }
            else if(str[i]=='Y'){
                    dp[i][1]+=dp[i-1][0]+dp[i-1][2];
            }
            else{
                dp[i][2]=dp[i-1][0]+dp[i-1][1];
            }
        }
        if(dp[i][0]>=2)dp[i][0]=2;
        if(dp[i][1]>=2)dp[i][1]=2;
        if(dp[i][2]>=2)dp[i][2]=2;

    }
    ll ans=0;
    if(str[n]=='?'){
        ans+=dp[n][0]+dp[n][1]+dp[n][2];
    }
    else{
            if(str[n]=='C'){
                ans=dp[n][0];
            }
            else if(str[n]=='Y'){
                    ans=dp[n][1];
            }
            else{
            ans=dp[n][2];
            }
        }
        if(ans>=2)
        cout<<"Yes"<else
        cout<<"No"<return 0;
} 

你可能感兴趣的:(codeforces)