bzoj1413

来源:互联网 发布:java关键字do的作用 编辑:程序博客网 时间:2024/06/06 01:32
右边实际小的时候:
1.左边left大于右边实际的时候,下一个left=右边实际  一直保持直到最后后手一定会达到胜态,因为先手先把一方取完
2.左边left等于右边实际的时候  下一个left=右边实际+1;
3.左边left小于右边实际且不为0的时候 下一个left=右边实际+1
3.左边left小于右边实际且为0的时候 下一个left=右边实际
右边实际大的时候且right!=0
1.左边left比右边实际大的时候 下一个left=右边实际-1
2.左边left等于右边实际的时候 下一个left=右边实际-1
3.左边left小于右边实际的时候
f.当左边left=右边right 的时候下一个left=右边实际
s.当左边left>右边right的时候 下一个left=右边实际  当右边=left+1的时候
后面先手不管怎么出手我们都能转化成前面的情况

t.当左边left<右边right的时候
左边left不等于0时:下一个left=右边实际 当左边过了到right-1的时候变成右边实际+1

左边left等于0的时候下一个left=右边实际
以上情况考虑左边数目1右边数目2

右边实际大的时候且right=0
1.左边left比右边实际大的时候 下一个left=右边实际
2.左边left比右边实际等于的时候 下一个left=右边实际+1
3.左边left小于右边实际的时候
f.左边等于0 那么 下一个left=右边实际

右边实际等于right的时候不用讨论了吧
直接等于fact就好了
中上:
其实你每次把左右两边考虑成数目为1或2的情况就好讨论了
然后你发现其实就和nim博弈是差不多的,只是我们不能用那个结论了
或许阔以变一下然后用,但是我不知道。

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;struct distt{int left, right;};distt l[1010][1010];int a[1010];int n, t;int getans(int fact, int std, int another){if (std > fact){if (another > fact)return fact;if (another == fact)return fact + 1;if (another <fact&&another!=0)return fact + 1;if (another == 0)return fact;}if (std == fact)return 0;else{if (std != 0){if (another >= fact)return fact - 1;else{if (std == another)return fact;if (another > std)return fact ;else{if (another != 0)return fact;if (another == 0)return fact - 1;}}}else{if (another > fact)return fact;if (another == fact)return fact + 1;else{if (another == 0)return fact;if(another!=0)return fact + 1;}}}}int main(){scanf("%d", &t);while (t--){scanf("%d", &n);for (int i = 1; i <= n; i++)scanf("%d", &a[i]);if (n == 1)printf("1\n");else{for (int i = 1; i <=n; i++)l[i][i].left = l[i][i].right = a[i];for (int ll = 2; ll <= n - 1; ll++){for (int i = 1; i <= n - ll + 1; i++){int j = i + ll - 1;l[i][j].left = getans(a[j], l[i][j - 1].right, l[i][j - 1].left);l[i][j].right = getans(a[i], l[i + 1][j].left, l[i + 1][j].right);}}if (l[2][n].left == a[1])printf("0\n");elseprintf("1\n");}}return 0;}


原创粉丝点击