题目大意:给你3种颜色的卡片若干张,你有两种操作:
1.挑选两张颜色一样的卡片变为一张那张颜色的卡片;
2.挑选两张颜色不一样的卡片变为低三种颜色的卡片吗;
问你最后会有什么情况;
题目解析:
不难发现每次操作之后卡片总数就减少一,为了记录各种卡片的个数,我们这里可以开一个三维dp[i][j][k];i表示取了第几次,因为最后肯定只剩1张卡片,而每次总数减少一,所以一共取了n-1次;j表示R的个数,k表示G的个数,而dp[i][j][k]本身的值就是B的个数;
状态方程很好理解,枚举即可;
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
int main()
{
int dp[201][201][201],r,n,b,g,i,j,k,sum;
string s;
while(scanf("%d",&n)!=EOF)
{
r=0;
b=0;
g=0;
cin>>s;
for(i=0;i<s.size();i++)
{
if(s[i]=='R')
r++;
else if(s[i]=='B')
b++;
else
g++;
}
sum=1+r+b+g;
for(i=0;i<=200;i++)
for(j=0;j<=200;j++)
for(k=0;k<=200;k++)
dp[i][j][k]=-1;
dp[1][r][b]=g;
for(i=1;i<=n;i++)
{
for(j=0;j<=200;j++)
{
for(k=0;k<=200;k++)
{
if(dp[i][j][k]!=-1)
{
if(j-1>=0&&k-1>=0)
dp[i+1][j-1][k-1]=sum-j-k+1-i;
if(j-1>=0&&sum-j-k-i-1>=0)
dp[i+1][j-1][k+1]=sum-j-k-i-1;
if(k-1>=0&&sum-j-k-i-1>=0)
dp[i+1][j+1][k-1]=sum-j-k-i-1;
if(j-1>=1)
dp[i+1][j-1][k]=sum-k-j-i;
if(k-1>=1)
dp[i+1][j][k-1]=sum-k-j-i;
if(sum-j-k-i-1>=1)
dp[i+1][j][k]=sum-j-k-i-1;
}
}
}
}
if(dp[n][0][1]==0)
cout<<"B";
if(dp[n][0][0]==1)
cout<<"G";
if(dp[n][1][0]==0)
cout<<"R";
cout<<endl;
}
return 0;
}