• JZOJ 5778


    Description

    被污染的灰灰草原上有羊和狼。有N只动物围成一圈,每只动物是羊或狼。

    该游戏从其中的一只动物开始,报出[1,K]区间的整数,若上一只动物报出的数是x,下一只动物可以报[x+1,x+K]区间的整数,游戏按顺时针方向进行。每只动物报的数字都不能超过M。

    若一只动物报了M这个数,它所在的种族就输了。问以第i只动物为游戏的开始,最后哪种动物会赢?

    Input

    第一行输入三个正整数N,M,K。

    接下来一行N个正整数,分别表示N只动物的种类,以顺时针的方向给出。0代表羊,1代表狼。

    Output

    一行输出N个整数,表示若从第i只动物开始,赢的动物的种类。同上,0代表羊,1代表狼。

    Sample Input

    Input 1

    2 9 2
    0 1


    Input 2

    6 499 5
    1 0 0 1 1 0


    Input 3

    10 100 10
    0 0 0 1 1 1 1 0 1 1


    Sample Output

    Output 1

    0 1


    Output 2

    0 1 1 1 1 0


    Output 3

    1 1 1 1 1 1 1 1 1 1


    Data Constraint

    对于60%的数据,1 ≤ N, M, K ≤ 500。

    对于100%的数据,1 ≤ N, M, K ≤ 5000。


    一开始以为结论博弈题,玩了玩发现好像并不是

    又以为是 SG 函数,心想只能打暴力了

    yy 了一下写了个 dp  (差点就写对了?

    一开始觉得破环成链复制出来 m 个很虚,也没敢接着想

    反正状态是错的:f[i][j] 表示第 i 个数第 j 个人选是必胜还是必败

    还有带个线段树优化成 O(n ^ 2 * logn)

    居然还有8分

    正解是这样的

    f[i][j] 表示 在位置 i 这个人选择 j 这个数是必胜还是必败

    最多每个人都选择增大 1 ,所以将人复制成为 n + m 个

    边界:所有人选 m 都是必败,第 n + m - 1 个人只能选 1, 也是必败,就不用更新他了

    倒着递推出之前的

    f[i][j] 从 f[i][j + 1] ~ f[i][j + k] 更新

    判断上一个人是不是队友,是队友只要有必胜态,此状态还是必胜

    不是队友只要有必胜态,此状态为必败态,否则必胜

    什么前缀和线段树什么的随便优化一下就好了


    代码:

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cctype>
    #include<cstdio>
    using namespace std;
    
    const int MAXN = 5005;
    
    int n, m, k;
    int per[MAXN << 1], f[MAXN << 1][MAXN];
    
    inline int rd() {
    	register int x = 0;
    	register char c = getchar();
    	while(!isdigit(c)) c = getchar();
    	while(isdigit(c)) {
    		x = x * 10 + (c ^ 48);
    		c = getchar();
    	}
    	return x;
    }
    
    int main() {
    	freopen("vode.in", "r", stdin);
    	freopen("vode.out", "w", stdout);
    	n = rd(); m = rd(); k = rd();
    	for(int i = 1; i <= n; ++i) per[i] = rd();
    	int ptr = n;
    	while(ptr < m + n) {
    		++ptr;
    		per[ptr] = per[ptr - n];
    	}
    	for(int i = n + m - 2; i >= 1; --i) {
    		int pre = 0;
    		for(int j = m - 1; j >= 1; --j) {
    			f[i][j] = ((per[i] == per[i + 1]) ? (!(pre == 0)) : (pre == 0)); 
    			pre += f[i + 1][j];
    			if(m - j + 1 >= k) pre -= f[i + 1][j + k];
    		}
    	}
    	for(int i = 1; i <= n; ++i) {
    		bool win = false;
    		for(int j = 1; j <= k; ++j) win |= f[i][j];
    		printf("%d ", win ? per[i] : (per[i] ^ 1));
    	}
    	return 0;
    }
    

      

    禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载 ,用户转载请注明出处:https://www.cnblogs.com/xcysblog/
  • 相关阅读:
    如何在CPU上优化GEMM(下)
    如何在CPU上优化GEMM(上)
    编译ONNX模型Compile ONNX Models
    深度学习加速器堆栈Deep Learning Accelerator Stack
    TVM部署和集成Deploy and Integration
    Relay张量集成
    TVM 架构设计
    NVIDIA Turing Architecture架构设计(下)
    NVIDIA Turing Architecture架构设计(上)
    antD——upLoad组件控制台报错404,405问题
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9446016.html
Copyright © 2020-2023  润新知