CCC是清华大学和某大学主办的比赛,我参加的是题比较简单的选拔赛。第五题当时没时间做了。后来回家把第五题写了。是dp(记忆化搜)。代码可能有错,请多指教。
#include <iostream>
using namespace std;
#define MAX 101
#define INF (1<<29)
int dp[MAX][MAX][2];
int lef[MAX],rig[MAX];
bool clr[MAX];
/*int dfs(int a)
{
int ans=0;
if (a==-1) return 0;
ans+=clr[a];
ans+=dfs(lef[a]);
ans+=dfs(rig[a]);
dp[a][ans][clr[a]]=0;
return ans;
}*/
int dfs(int a,int num,bool k)
{
int ans=0;
if (dp[a][num][k]!=-1) return dp[a][num][k];
if (k==0)
{
if (lef[a]==-1||rig[a]==-1) return INF;
ans=dfs(lef[a],num,1)+dfs(rig[a],num,1)+(clr[a]!=k);
}
if (num-k<0) return INF;
if (k==1)
{
if (lef[a]==-1 && rig[a]==-1) return num-k==0?0:INF;
ans+=(clr[a]!=k);
if (lef[a]!=-1)
ans+=min(dfs(lef[a],num-k,1),dfs(lef[a],num-k,0));
if (rig[a]!=-1)
ans+=min(dfs(rig[a],num-k,1),dfs(rig[a],num-k,0));
}
return dp[a][num][k]=ans;
}
int main()
{
int n ,ret=INF;
char in[5];
int root,leave;
scanf("%d",&n);
for (int i=0;i<n;i++)
{
scanf("%d%d%s",lef+i,rig+i,in);
if (lef[i]>0)lef[i]--;
if (rig[i]>0)rig[i]--;
if (in[0]=='R') clr[i]=0;
else clr[i]=1;
}
memset(dp,0xff,sizeof(dp));
//dfs(root);
root=0;leave=0;
for (int i=leave;i<=n;i++)
ret=min(ret,min(dfs(root,i,0),dfs(root,i,1)));
printf("%d\n",ret);
return 0;
}
我把==打成!=了,查了一个多小时!