2017.10.10 取石子游戏 失败总结

来源:互联网 发布:数据库mdf文件过大 编辑:程序博客网 时间:2024/06/07 03:50

博弈,只是把取的条件变了一下,,就不会了

首先对于一个区间,若他为必胜,则往左右两边只有加唯一一个数会使他必败,略等同于nim的情况

然后剩下的递推其实是构造类问题。

由于每次只能取最左边和最右边的,所以状态可以从两边转移

一边构造理想情况一边更新

更详细的做法:点击打开链接


本质就是区间dp+构造,,只是证明、结论考虑因素比较多所以不好推


码:


#include<iostream>#include<cstdio>using namespace std;int T,a[1005],l[1005][1005],r[1005][1005],n,i,j;int main(){    scanf("%d",&T);    while(T--)    {scanf("%d",&n);for(i=1;i<=n;i++)scanf("%d",&a[i]),l[i][i]=r[i][i]=a[i];if(n==1){printf("1\n");continue;}for(i=n-1;i>=1;i--)for(j=i+1;j<=n;j++){    int x=l[i][j-1],y=r[i][j-1],z=a[j];    if(z==y){ l[i][j]=0;}    else    {        if((z<x&&z<y)||(z>x&&z>y)){l[i][j]=z;}        if(x<=z&&z<y){l[i][j]=z+1;}        if(x>=z&&z>y){l[i][j]=z-1;}    }    x=l[i+1][j],y=r[i+1][j],z=a[i];    if(z==y){ r[i][j]=0;}    else    {        if((z<x&&z<y)||(z>x&&z>y)){r[i][j]=z;}        if(x<=z&&z<y){r[i][j]=z+1;}        if(x>=z&&z>y){r[i][j]=z-1;}    } }        if(a[1]==l[2][n])printf("0\n");    else printf("1\n");    } } 


原创粉丝点击