ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【笔记】轮廓线dp

2022-01-16 11:31:08  阅读:155  来源: 互联网

标签:int max 笔记 玩家 轮廓线 INF include 递推 dp


参考
用沿着格子边的线刻画一条轮廓线,状态满足字典序,可以直接递推

[九省联考 2018] 一双木棋 chess
这种类似min-max博弈的递推思路和期望dp挺类似的,设 f[s][0/1] 表示当前棋盘状态 s,当前轮到玩家 0/1 时,当前玩家之后可以获得的最大的自己收益与对方的差值,若 s 经过一步到达 ss,则有 \(f[s][0/1] = max\lbrace A[x,y][0/1] - f[ss][1/0]\rbrace\),对当前的 s,只有对应轮到的那个玩家才能进行递推

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 1048580;
int N, M, A[10][10][2], f[INF][2];
bool ok(int s)
{
	int b=0; while (s) b++, s-=(s&(-s));
	return b==N;
}
int main()
{
	scanf("%d%d", &N, &M);
	for (int i=1; i<=N; i++)
		for (int j=1; j<=M; j++) scanf("%d", &A[i][j][0]);
	for (int i=1; i<=N; i++)
		for (int j=1; j<=M; j++) scanf("%d", &A[i][j][1]);
	//memset(f, 0xc0, sizeof(f));
	//f[(1<<N)-1][(M*N+1)&1] = 0;
	int mx = (1<<(N+M))-1;
	for (int s=1; s<=mx; s++) if (ok(s)) {
		int x=0, y=M+1, t=0; bool flg=1;
		for (int b=0; b< N+M; b++)
			if ((1<<b)&s) x++, t+=y-1; else y--;
		t &= 1, x = 0, y = M+1;
		for (int b=0; b< N+M; b++) {
			if ((1<<b)&s) x++; else y--;
			if (b && ((1<<b)&s) && !((1<<(b-1))&s)) {
				int ss = (s^(1<<b))|(1<<(b-1));
				if (flg) f[s][t] = A[x][y][t]-f[ss][t^1], flg = 0;
				else f[s][t] = max(f[s][t], A[x][y][t]-f[ss][t^1]);
			}
		}
	}
	printf("%d\n", f[((1<<N)-1)<<M][0]);
}

标签:int,max,笔记,玩家,轮廓线,INF,include,递推,dp
来源: https://www.cnblogs.com/zhyh/p/15809021.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有