• 【LOJ】#2886. 「APIO2015」巴厘岛的雕塑 Bali Sculptures


    题解

    感觉自己通过刷水题混LOJ刷题量非常成功

    首先是二进制枚举位,判是否合法
    要写两个solve不是很开心,(A)不为1的直接记录状态(f[i][j])为能否到达前(i)个分成(j)段,转移(n^3)

    (A)为1的相当于在一张拓扑图上求到(N)的最短路是否小与(B),连边方式即为如果(sum[j] - sum[k])是二分值的一个子集则(k)(j)有边

    代码

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define pdi pair<db,int>
    #define mp make_pair
    #define pb push_back
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define eps 1e-8
    #define mo 974711
    #define MAXN 505
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;char c = getchar();T f = 1;
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 + c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    int N,A,B,l;
    int64 y[2005],sum[2005];
    int dp[2005];
    bool f[105][105];
    void Solve1() {
        int64 ans = 0;
        for(int i = l ; i >= 0 ; --i) {
    	int64 t = ans + (1LL << i) - 1;
    	
    	for(int j = 1 ; j <= N ; ++j) {
    	    dp[j] = N + 1;
    	    for(int k = 0 ; k < j ; ++k) {
    		if(((sum[j] - sum[k]) & t) == (sum[j] - sum[k])) dp[j] = min(dp[j],dp[k] + 1);
    	    }
    	}
    	if(dp[N] > B) {ans |= (1LL << i);}
        }
        out(ans);enter;
    }
    void Solve2() {
        int64 ans = 0;
        for(int i = l ; i >= 0 ; --i) {
    	int64 t = ans + (1LL << i) - 1;
    	memset(f,0,sizeof(f));
    	f[0][0] = 1;
    	for(int j = 1 ; j <= N ; ++j) {
    	    for(int k = 0 ; k < j ; ++k) {
    		if(((sum[j] - sum[k]) & t) == (sum[j] - sum[k])) {
    		    for(int h = 1 ; h <= j ; ++h) {
    			f[j][h] |= f[k][h - 1];
    		    }
    		}
    	    }
    	}
    	bool flag = 0;
    	for(int k = A ; k <= B ; ++k) {
    	    if(f[N][k]) {flag = 1;break;}
    	}
    	if(!flag) ans |= (1LL << i);
        }
        out(ans);enter;
    }
    void Init() {
        read(N);read(A);read(B);
        for(int i = 1 ; i <= N ; ++i) {read(y[i]);sum[i] = sum[i - 1] + y[i];}
        int64 t = sum[N];
        l = 0;
        while(t) {++l;t >>= 1;}
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Init();
        if(A == 1) Solve1();
        else Solve2();
    }
    
  • 相关阅读:
    01Tensorflow学习之Tensorflow基本介绍
    C#四舍五入说明
    3类与对象——重拾Java
    1Java语言概述——重拾Java
    Android 字体效果
    Python相关资料收集
    2013.11.23思科研发中心面试
    【转】理解同步与异步
    OpenCV中的SURF算法介绍
    OpenCV中Kinect的使用(3)
  • 原文地址:https://www.cnblogs.com/ivorysi/p/10139235.html
Copyright © 2020-2023  润新知