zoukankan      html  css  js  c++  java
  • BZOJ1802: [Ahoi2009]checker

    这种需要手玩/多考虑几种情况的题不手玩不好好考虑就只有 20 tps

    主要要考虑到可能会有相邻的两个红格子,
    这样他们俩是可以通过不断放/跳棋子来 reach 任何一个格子

    那之后怎么求总数?

    其实就是 f[i] = f[i - 1] + f[i - 2] / f[i] = f[i + 1] + f[i + 2]

    红色格子 f 值为 1,其余为 INF

    由于 1 位置是初始棋子,不能算入

    注意最大到 1e15,memset的数小了是会 GG 的


    代码:

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <cctype>
    using namespace std;
    
    typedef long long ll;
    const int MAXN = 1005;
    
    int n;
    int seq[MAXN];
    ll ans1, ans2;
    ll f[MAXN];
    bool hasnei;
    
    int main() {
    	scanf("%d", &n);
    	for (int i = 1; i <= n; ++i)
    		scanf("%d", &seq[i]);
    	ans1 = (n >> 1);
    	for (int i = 2; i < n; i += 2) 
    		if (seq[i]) --ans1;
    	memset(f, 0x3f, sizeof(f));
    	for (int i = 3; i <= n; ++i) {
    		if (seq[i - 1] && seq[i]) hasnei = true;
    	}
    	if (!hasnei) {
    		printf("%lld
    %lld
    ", ans1, (n >> 1) - ans1);
    	} else {
    		for (int i = 2; i <= n; ++i) 
    			if (seq[i]) f[i] = 1ll;
    		ans2 = 0;
    		for (int i = 2; i <= n; ++i) {
    			f[i] = min(f[i], f[i - 1] + f[i - 2]);
    		}
    		for (int i = n; i >= 2; --i) {
    			f[i] = min(f[i], f[i + 1] + f[i + 2]);
    		}
    		for (int i = 2; i < n; i += 2) {
    			ans2 += f[i];
    		}
    		printf("0
    %lld
    ", ans2);
    	}
    	return 0;
    }
  • 相关阅读:
    如何解决加载动态链接库DLL失败,返回0,GetLastError返回错误码126
    如何实现点击激活窗体同时窗体不跑到最前覆盖其他窗体
    数据库04
    数据库03
    数据库02
    数据库01
    Linux02
    Linux01
    软件质量
    HTML04
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9831533.html
Copyright © 2011-2022 走看看