当保持在一条线上时,收集总价值最大的卡片(只从角落提取)
Collect cards of largest total value when kept in a line (extraction only from the corners)
考虑下面的游戏。
经销商产生序列s1…Sn张牌,面朝上每张牌si都有一个值vi。然后两名玩家轮流从序列中取出一张牌,但是只能选择RST或(剩余)序列的最后一张牌。目标是收集卡片最大总价值。(例如,你可以把卡片想象成不同面值的钞票。)
给出一个O(n^2)算法来计算第一个参与人的最优策略(只是最大可获得的代码)。
我已经尝试解决它的合法和可能解决它这里是我的代码…数组cards包含每张卡的值。卡片的第0个元素是未使用的和浪费的(基础索引1)!
#include<bits/stdc++.h>
using namespace std;
int main()
{
int cards[]={0,2,100,101,1};
int n=4;
int i,j,l,sum=204;
int dp[n+1][n+1];
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
dp[i][i]=cards[i];
for(l=2;l<=n;l++)
{
for(i=1;i<=n-l+1;i++)
{
j=i+l-1;
dp[i][j]=max(cards[i]-dp[i+1][j],cards[j]-dp[i][j-1]);
}
}
printf("%dn",(sum+dp[1][n])/2);
return 0;
}
在最后一个打印语句中,我打印了(sum+dp[1][n])/2,因为元素是2n, n将被包括在内,其余的n将被减去,当我执行这个操作时,我得到了包含值的和。
虽然它给出了正确的答案,但我还是说不出dp[I][j]到底代表什么!!它不代表最大可获得的价值(因为它不会给我的价值直接)。我的另一个问题是,它表示什么?
有其他的思路来解决这个问题吗?
在你发布的代码中,dp[i][j]
代表第一和第二玩家可以从子字符串i..j
: dp[i][j]=max(first[i][j]-second[i][j])
开始的最大差值(这不是编程语言公式,只是为了给出想法),这里我们称第一玩家为从该位置开始的玩家。
考虑一个子字符串i..j
。第一个玩家(A)可以选择拿第一张还是最后一张牌。如果他拿了第一张牌,他将得到cards[i]
,但是他的对手(B)将从子串i+1..j
开始。他会尽他最大的努力,让对他的有利的差异dp[i+1][j]
,即差异将是pointsB - pointsA = dp[i+1][j]
。但是对于我们的位置i,j
,我们对pointsA-pointsB
的差异感兴趣,所以我们取-dp[i+1][j]
并记住card[i]
,因此
dp[i][j]=card[i]-dp[i+1][j]
还有另一种变体,即取最后一张牌,结果为
dp[i][j]=card[j]-dp[i][j+1]
显然,玩家会选择最好的选项,因此你应该取两个值中的最大值。
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么istream不支持右值提取
- 如何设置一个范围来提取我想要获得的信息
- 视觉工作室项目.提取源文件夹名称
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- 从字符串中提取整数并形成一个数组
- C ++中的StringStream有助于使用向量从字符串中提取逗号分隔的整数,而不是空格分隔的整数,为什么?
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- 从 std::vector<无符号字符>切片中提取 int?
- 在C++中使用重载提取运算符时出现问题
- 在 Qt(C++) 中使用 QProcess 解压缩 - 提取目录问题
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- 无法从 std::string 中提取C++ Unicode 符号
- 如何从也包含C++字母的文本文件中提取某些数字?
- 如何从适合一定范围的数字中提取数字?
- C++从通用引用中提取实际类型
- 从运行服务的应用程序代码中提取窗口句柄
- 如何在字符串中找到字符,然后在C++中提取其余的字符串
- 当保持在一条线上时,收集总价值最大的卡片(只从角落提取)