JZOJ 5407. 【NOIP2017提高A组集训10.21】Deep
2017-10-22 06:48
411 查看
题目大意
双方分别有A,B张牌,A先手。A和B每次可以选择2个操作:
①出牌,让传送门的值+1。
②不出牌,让对方得分加上传送门的值,然后传送门的值变为0。
注意,当自己的牌数>0且传送门的值为0时不能进行②操作。
题解
打个表发现,其实结论很显然。如果A>0,B>0,答案为A-B-2,否则为A-B。此结论可以证明。
其实策略不止一种。
策略1:后手总是存在这样的策略:将对方的牌打剩最后一张,然后开始出牌。
因为一旦后手选择出牌,则先后手互换,先手有类似的策略。
策略2:B可以将A的牌数消耗至B-1张,然后双方你一张我一张然后你不出。那么这个阶段A和B得分可以抵消。最后B还剩一张牌,B+1分,得到上述结论。
总结
①这道题最重要的是知道显然有结论。②问题是怎么打表。
按照博弈规则,A希望分差A-B越大,B希望A-B越小。
那么记录一下当前先手是谁,到A走的时候,就返回得分的max,B就返回得分的min。
博弈的代码(非AC代码)
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; int ans,a,b,T; int dg(int a,int b,int door,int v,int bz){ if(!a&&!b&&!door)return v; if(bz){//A出牌,max环节 int mx=-2147483647; if(door!=0||!a)mx=max(mx,dg(a,b,0,v-door,0)); if(a>0)mx=max(mx,dg(a-1,b,door+1,v,0)); return mx; }else{//B出牌,min环节 int mi=2147483647; if(door!=0||!b)mi=min(mi,dg(a,b,0,v+door,1)); if(b>0)mi=min(mi,dg(a,b-1,door+1,v,1)); return mi; } } int main(){ freopen("deep.in","r",stdin); freopen("deep.out","w",stdout); scanf("%d",&T); while(T--){ scanf("%d%d",&a,&b); ans=dg(a,b,0,0,1); printf("%d\n",ans); } return 0; }
相关文章推荐
- JZOJ5407. 【NOIP2017提高A组集训10.21】Deep
- JZOJ 5407. 【NOIP2017提高A组集训10.21】Deep
- JZOJ 5408. 【NOIP2017提高A组集训10.21】Dark
- 【JZOJ5408】【NOIP2017提高A组集训10.21】Dark
- 【JZOJ 5409】【NOIP2017提高A组集训10.21】Fantasy
- [JZOJ5439]【NOIP2017提高A组集训10.21】Fantasy
- JZOJ5409. 【NOIP2017提高A组集训10.21】Fantasy
- JZOJ 5409 【NOIP2017提高A组集训10.21】Fantasy
- JZOJ 5408 【NOIP2017提高A组集训10.21】Dark
- 【JZOJ 5417】【NOIP2017提高A组集训10.24】方阵
- 【JZOJ 5413】【NOIP2017提高A组集训10.22】清兰
- 【JZOJ5424】【NOIP2017提高A组集训10.25】凤凰院凶真
- JZOJ 5425. 【NOIP2017提高A组集训10.25】数论
- 【JZOJ 5431】【NOIP2017提高A组集训10.28】序列操作
- [置顶] 【JZOJ5429】【NOIP2017提高A组集训10.27】排列
- jzoj5436 【NOIP2017提高A组集训10.30】Group
- JZOJ 5437. 【NOIP2017提高A组集训10.31】Sequence
- 【JZOJ 5410】【NOIP2017提高A组集训10.22】小型耀斑
- 【JZOJ5410】【NOIP2017提高A组集训10.22】小型耀斑
- [JZOJ5422]【NOIP2017提高A组集训10.25】天才绅士少女助手克里斯蒂娜