我在topcoder上尝试了一个简单的dp问题,就像这样
Petr和Snuke正在玩一场合作纸牌游戏。游戏开始了 使用特殊卡片:每张卡片都标有一些正整数。 卡片上的整数不一定是不同的。在比赛开始时,彼得手里拿着一些牌 而Snuke手里拿着所有其他牌。你得到了 int [] s petr和snuke描述了开头的状态 游戏:皮特的元素是彼得卡上的数字和 snuke的元素是Snuke卡片上的数字。
在比赛期间,玩家将把他们的一些牌放到一张牌上 桩。最初,桩是空的。球员采取交替 转身,彼得先走了。在每个回合中,如果当前玩家没有 他手里拿着牌,游戏结束了。否则,玩家必须制作 一个有效的举动。有效动作有三种类型:如果是 桩是空的,玩家可以选择任何卡并将其放置在 桩。如果堆不是空的,玩家可以选择任何卡和 把它放在桩顶上。但是,这一举动只有在有效的情况下才有效 新卡上的号码严格大于卡上的号码 这是以前在桩顶上。玩家可以永远 选择他的一张牌并吃掉它。
Petr和Snuke有一个共同的目标:他们想用as创造一堆 尽可能多张牌。返回桩的大小 游戏,假设他们合作并以最佳方式玩游戏。
I / O:
{2, 5}
{3, 1}
Returns: 3
One optimal way is as follows.
Petr puts 2 onto the pile.
Snuke puts 3 onto the pile.
Petr puts 5 onto the pile.
Snuke eats 1.
The game ends because Petr has no cards in his hand.
{1,1,1}
{1,1,1}
returns 1
我已将定义为dp
的{{1}}函数定义为Petr的dp[i][j]
卡和Snuke' ith
上的最大牌。卡并尝试了以下代码:
jth
为简单起见,我只想尝试两个元素。如果卡上的整数是不同的,则此解决方案有效。我有点困惑,想出非独特的案例。对于等整数,for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if(i==0||j==0)
dp[i][j]=1;
else if(a[i]>b[j])
dp[i][j] = max(dp[i-1][j]+1, dp[i][j-1]);
else if(a[i]<b[j])
dp[i][j]= max(dp[i-1][j], dp[i][j-1]+1);
if(a[i]==b[j])
dp[i][j] = dp[i-1][j-1]; //This does not work
}
}
cout << dp[2][2];
状态的定义是什么?
答案 0 :(得分:0)
我认为使用应该首先按顺序对两个玩家的元素进行排序,因为移动时较小的值总是比较大的值更好。
之后你dp:
F [i] [j] [u] [v]是Petr的第i张牌和Snuke的牌桌上的最大牌,其中{j,v} = {0,1 }:j = 0 =&gt; Petr吃第i张牌,1 =&gt;彼得把i_th放到了馅饼上。与v相同。
然后
petr&#t>转向:i&gt; u:
F [i] [0] [u] [v] = max(F [i-1] [0] [u] [v],F [i-1] [1] [u] [v] );
F [i] [1] [u] [v] = max(F [i-1] [0] [u] [v],F [i-1] [1] [u] [v] )1;
Snuke转:i = u:
F [i] [j] [u] [0] = max(F [i] [j] [u-1] [0],F [i] [j] [u-1] [1] );
F [i] [j] [u] [1] = max(F [i] [j] [u-1] [0],F [i] [j] [u-1] [1] )1;
这是我的想法,我还没有尝试过,但我希望它会对你有所帮助!