IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【博弈】取石子游戏(P2599) -> 正文阅读

[数据结构与算法]【博弈】取石子游戏(P2599)

正题

P2599


题目大意

给n堆石子,第 i 堆有 a i a_i ai? 个石子,每次可以从最左边或者最右边的一堆里面取若干个,两个人轮流取,问先手是否存在必胜策略


解题思路

l i , j l_{i,j} li,j? 为在 [ i , j ] [i,j] [i,j] 右边添加一堆大小 l i , j l_{i,j} li,j? 的石子,会使得先手必败, r i , j r_{i,j} ri,j?同理

首先证明 l i , j l_{i,j} li,j? 只存在一个

如果存在两个 l i , j l_{i,j} li,j?,那么先手显然可以从大的直接操作为小的,那么先手必胜,不满足先手必败,所以最多有一个 l i , j l_{i,j} li,j?

接下来证明一定存在 l i , j l_{i,j} li,j?

如果不存在 l i , j l_{i,j} li,j?,那么左边无论加多少个数都是必胜状态
如果先手选左边那么必定到必胜状态,不满足先手必胜,所以先手肯定选右边
选了若干数后,一定满足无论左边加的是多少都必败,那么后手在左边选一个数则又回到了必败状态,不满足先手必胜

综上,必定存在 l i , j l_{i,j} li,j?

同理必定存在 r i , j r_{i,j} ri,j? 且只存在一个

接下来考虑如何转移

对于 l i , j l_{i,j} li,j? 的求解,考虑从 [ i , j ? 1 ] [i,j-1] [i,j?1] 转移,那么必定和 l i , j ? 1 , r i , j ? 1 l_{i,j-1},r_{i,j-1} li,j?1?,ri,j?1? 有关,令 L = l i , j ? 1 , R = r i , j ? 1 L=l_{i,j-1},R=r_{i,j-1} L=li,j?1?,R=ri,j?1?

  1. R = a j R=a_j R=aj?,那么先手就是必败的,所以 l i , j = 0 l_{i,j}=0 li,j?=0
  2. 对于其他情况,其实就是把必败的决策点除外,令左右必胜决策点数相同即可
    如果先手左边拿到 L,那么右边直接取空则先手必败(右边同理)
    如果先手左边拿完,那么对于后手就是必胜得状态
    否则先手左边拿多少必胜决策,右边拿同样多即可

最后判断 a 1 a_1 a1? 是否等于 l 2 , n l_{2,n} l2,n? 即可

时间复杂度 O ( n 2 T ) O(n^2T) O(n2T)


code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 1010
using namespace std;
int T,n,a[N],l[N][N],r[N][N];
int main()
{
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		for(int i=1;i<=n;++i){
			scanf("%d",&a[i]);
			l[i][i]=r[i][i]=a[i];
		}
		for(int len=2;len<n;++len)
			for(int i=1;i<=n-len+1;++i){
				int j=i+len-1,L,R;
				L=l[i][j-1];R=r[i][j-1];
				if(a[j]==R)l[i][j]=0;
				else if(L<=a[j]&&a[j]<R)l[i][j]=a[j]+1;
				else if(a[j]<L&&a[j]<R)l[i][j]=a[j];
				else if(L<a[j])l[i][j]=a[j];
				else l[i][j]=a[j]-1;
				L=l[i+1][j];R=r[i+1][j];
				if(a[i]==L)r[i][j]=0;
				else if(R<=a[i]&&a[i]<L)r[i][j]=a[i]+1;
				else if(a[i]<R&&a[i]<L)r[i][j]=a[i];
				else if(R<a[i])r[i][j]=a[i];
				else r[i][j]=a[i]-1;
			}
		if(l[2][n]!=a[1])puts("1");
		else puts("0");
	}
	return 0;
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-15 00:24:47  更:2022-04-15 00:25:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:39:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码