这是来自澳大利亚信息学奥林匹克竞赛的问题
问题是:
你听说过我的朋友Melodramia吗?这是一片禁林和无边无际的沼泽地,冲刺英雄和潇洒的女主人公。这里有两条龙,Rose和Scarlet,尽管他们有竞争优势,但他们是最好的朋友。
Rose和Scarlet喜欢玩Binary Snap,两个玩家的游戏。游戏使用一副牌,每张牌都有一个从1到N的数字标签。每张可能的标签有两张牌,总共制作2N张牌。游戏如下:
玫瑰洗牌并将它们面朝下放在Scarlet面前。 然后,Scarlet选择顶部牌,或从牌组中选择第二张牌并展示它。 Scarlet继续这样做,直到甲板空了。如果她在任何时候显示的卡片与她透露的上一张卡片的标签相同,那么这些卡片就是一对龙牌,无论哪条龙都喊叫“Snap!”#39;首先获得一分。 在经历了数千年的比赛之后,龙们注意到拥有更多可能的龙对将经常导致更激动人心的比赛。正是因为这个原因,他们召集你,村里的计算机工作者,编写一个程序,按照洗牌的牌中的卡片顺序读取,并输出龙可以找到的最大龙对数。我不知道如何解决这个问题。我想到了一些错误的东西(选择所有卡的最大值,与之前每张卡的出现次数相比)
这是我现在的代码:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream fin("snapin.txt");
ofstream fout("snapout.txt");
int n;
fin>>n;
int arr[(2*n)+1];
for(int i=0;i<2*n;i++){
fin>>arr[i];
}
int dp[(2*n) +1];
int maxi = 0;
int pos[n+1];
for(int i=0;i<n+1;i++){
pos[i] = -1;
}
int count = 0;
for(int i=2;i<(2*n)-2;i++){
if(pos[arr[i]] == -1){
pos[arr[i]] = i;
}else{
dp[i] = pos[arr[i]]+1;
maxi = max(dp[i],maxi);
}
dp[i] = max(dp[i],maxi);
}
fout<<dp[2*n -1];
}
答案 0 :(得分:0)
好的,让我们先解决问题的一些基本测量:
这是指数增长,每个优化科学家都是最受欢迎的挑战。
对蛮力方法不满意吗?我也不是。
在我们找到最佳解决方案之前,让我们休息一下,探讨马尔可夫假设是什么以及它对我们意味着什么。它使用不同的词汇显示在不同的领域,但我只是以一种对涉及游戏玩法选择的这个问题特别有用的方式来解释它:
当且仅当您可以选择的选项仅取决于您现在拥有的内容,而不仅仅取决于您是如何获得时,过程就是Markov。
一个糟糕但经常使用的现实世界的例子是股票市场。短期和长期资本收益之间的税收差异不仅会使历史在很小程度上变得重要,而且投资者会进行趋势分析并记住以前股票的做法,从而大大影响未来的行为。 更好的例子,尤其是StackOverflow,是图灵机和计算机处理器的例子。您的程序接下来要做什么取决于当前指令指针和内存的内容,而不是因为被覆盖的内存历史。但还有更多。正如我们稍后将看到的那样,Binary Snap问题可以表述为Markov。
现在让我们谈谈是什么让马尔可夫假设如此重要。为此,我们将使用旅行商问题。不,旅行国际推销员问题。还是太乱了。让我们试试“单一入境签证问题的旅行国际推销员”。但我们将简要介绍它们中的所有三个:
销售人员必须访问N个城市的潜在买家。计划一个销售人员的行程,最小化访问所有N个城市的总成本(变化:至少一次/恰好一次),给定矩阵a j,k ,这是从城市 j 到城市 k 的旅行费用。 另一个变化是起始城市是否预先确定。
销售人员需要访问的城市分为两个(或更多)国家。一部分城市有边境口岸,并有所有城市的旅行选择。其他城市只能到达同一个国家或边境设施的城市。 或者,不要使用边境城市,而是使用拥有国际机场的城市。最终不会有所作为。 这个问题的成本矩阵看起来很像多米尼加共和国的旗帜。允许A国内城之间的旅行,以及B国(蓝色田野)内陆城市之间的旅行。边境城市与这两个国家的内陆和边境城市相连(白色十字架)。在A国内城和B国之间的直接旅行是不可能的(红色区域)。
现在,推销员不仅需要访问这两个国家的城市,而且他只能跨越边境一次。 (对于旅行狂热分子,假设他在第三个国家开始,并且两个国家都有单次入境签证,所以他不能访问A中的一些,全部是B,然后返回A,其余的)。
让我们先看一个非常简单的案例:只有一个边境城市。我们将使用另一个技巧,即通过归纳证明的技巧:我们假设所有小于当前问题的问题都可以解决。 当销售人员到达边境城市时,马尔可夫假设应该是相当明显的。无论他通过A国的哪条道路,他在B国都有完全相同的路径选择。 但这里有一个非常重要的观点:通过国家A的任何一条通往边界的道路以及从边境开始通过国家B的任何道路都可以合并成一个可行的完整行程。如果我们有两个完整的行程 x 和 y ,并且 x 在A国花费的钱比 y 花费的多,那么即使 x 的总成本低于 y 的总成本,我们也可以使用 y 在国家A和国家B中 x 的部分。我将称之为“拼接”。 Markov假设让我们通过使通往边境的所有道路可以互换来实现它! 事实上,我们可以只看到A国的城市,选择最好的边境路线,并且尽快(在我们的计划中)销售人员跨入B,忘记所有其他选择。 这意味着不是要考虑阶乘(N A )*阶乘(N B )路线,而是只有阶乘(N A )+阶乘(N <子>乙子>)。这几乎是因子(N A )倍。哇,这马可夫的事情有用还是什么?
好的,这太简单了。让我们把N AB 边界城市而不是一个城市弄得一团糟。现在,如果我的路径 x 在国家B中花费较少,路径 y 在A国花费较少,但是他们越过不同城市的边界,我可以'只是将它们拼接在一起。所以我必须再次跟踪所有城市的所有路径,对吧? 不完全是。如果除了最好的 y 路径之外,不是丢弃通过国家A的所有路径,而是实际上在每个边界城市中保留一条路径(在同一个边界城市中结束的所有路径的最低成本),该怎么办? 。现在,对于我在国家B看到的 x 的任何路径,我有一个路径 y endpt(x) ,它使用相同的边界城市,与它拼接。所以我必须解决国家A和国家B划分每个N AB 次以找到完整行程的最佳拼接,对于N AB 阶乘的总工作量(N < sub> A )+ N AB 阶乘(N B )仍然优于阶乘(N A )*阶乘(N <子>乙子>)。
充分开发工具。让我们回到龙,因为它们是微妙的,快速的愤怒,我不想被吃掉或烧焦到清脆。
我声称在Binary Snap游戏的任何一个步骤T,如果我们考虑我们的“位置”一对(卡片刚绘制,卡片在甲板顶部),Markov假设将成立。这些是决定我们未来选择的唯一因素。无论我们以前做过什么,所有在牌组顶部下面的牌都必须是相同的顺序。而且为了知道是否用下一张卡计算 Snap!,我们需要知道最后一张卡。就是这样! 此外,最后绘制的卡片上有N个可能的标签,并且甲板上的顶部卡片可能有N个,总共N 2 “边境城市”。当我们开始玩游戏时,第一个回合有两个选择,第二回合有两个选择,第三回合有两个选择,所以我们从2个 T 可能的游戏状态开始(以及Snap的数量! s为每个)。但是,通过鸽子原理,当2 T > N 2 ,其中一些戏剧必须以完全相同的游戏状态(“边境城市”)结束,当发生这种情况时,我们只需要保持&#34;支配&#34 ;在那里获得最高分的一个。 最终复杂性界限:2 * N次步长,来自不超过N 2 游戏状态,每次有2个绘制选择,等于4 * N 3 模拟绘制的上限。 这意味着同样的万亿计算允许我们用蛮力方法做N = 20,现在允许N = 8000左右。 这让龙很开心,这让我们活得很好。
实施说明:由于挑战没有要求抽奖顺序,只是可达到的最高数量的快照,除了卡片的初始订购之外,所有你要跟踪的数据是时间T,和你可以拥有的最佳分数的二维数组(N行,N列),并在时间T达到该状态。
真实世界的应用:如果采用这种方法并将其应用于使用卷积纠错码接收信号的数字无线电(固定均匀比特定时,离散信号电平),则需要使用维特比解码器。如果你将它应用于获得的医学数据,具有可变的时间间隔和连续的信号水平,并添加一些其他粗糙的数学,你得到my doctoral project。