問題
http://community.topcoder.com/stat?c=problem_statement&pm=13912&rd=16523
解き方
dpの問題。
1.どのような順序で処理されるか
→petr、snukeが順番に1つずつ出していく
2.前の状態としてどのような状態があればよいか
→前に出されたカードと、それまでに重ねられたカードの数
dp[一番上のカードの数字]= 重ねられたカードの数の最大値とし、
毎ターンできるだけ小さな数字でカードを重ねていけば良い。
問題文中の取ることが出きる動作のうち、1枚カードを食べるというのは
要はパスしてもよいというのがわかれば上記に帰着できそうだった。
コード
class YetAnotherCardGame {
public: int maxCards(vector<int> petr, vector<int> snuke) {
int n=petr.size();
int dp[101];
memset(dp,0,sizeof(dp));
sort(all(petr));
sort(all(snuke));
FORE(i,0,n){
for(int x=100;x>=0;x--){
FORE(j,0,n)if(petr[j]>x){
dp[petr[j]]=max(dp[petr[j]],dp[x]+1);
break;
}
}
for(int x=100;x>=0;x--){
FORE(j,0,n)if(snuke[j]>x){
dp[snuke[j]]=max(dp[snuke[j]],dp[x]+1);
break;
}
}
}
return *max_element(dp,dp+101);
}
};
public: int maxCards(vector<int> petr, vector<int> snuke) {
int n=petr.size();
int dp[101];
memset(dp,0,sizeof(dp));
sort(all(petr));
sort(all(snuke));
FORE(i,0,n){
for(int x=100;x>=0;x--){
FORE(j,0,n)if(petr[j]>x){
dp[petr[j]]=max(dp[petr[j]],dp[x]+1);
break;
}
}
for(int x=100;x>=0;x--){
FORE(j,0,n)if(snuke[j]>x){
dp[snuke[j]]=max(dp[snuke[j]],dp[x]+1);
break;
}
}
}
return *max_element(dp,dp+101);
}
};