zoukankan      html  css  js  c++  java
  • [APIO2015]巴厘岛的雕塑

    刚开始看错题,以为是每一组或起来,求和的最小值,然后就瞎写了个dp,状态根本无法转移竟然过了六个点也是醉了

    这个题根据数据可以分成两部分,可以按位贪心检验

    对于n<=100的数据每一位直接n^3的dp就可以了

    然后对于n>100的数据,A相当于没有限制,对每一位可以直接搞, g[i]代表到第i个雕塑至少分多少组才能符合要求

     1 #define MAXN 2010UL
     2 #include <cstdio>
     3 #include <cstring>
     4 
     5 using namespace std;
     6 
     7 typedef long long ll;
     8 
     9 int lg, n, B, A, f[110][110], g[MAXN];
    10 ll ans, sum[MAXN];
    11 
    12 void Solve1() {
    13     ll st = 0;
    14     for(int l = lg ; l >= 0 ; -- l) {
    15         memset(f, false, sizeof(f));
    16         f[0][0] = true;
    17         for(int k = 1 ; k <= B ; ++ k) {
    18             for(int i = k ; i <= n ; ++ i) {
    19                 for(int j = k-1 ; j < i ; ++ j) {
    20                     if(f[k-1][j]&&(((sum[i]-sum[j])&(st|(1ll<<l)))==0)) {
    21                         f[k][i] = true;
    22                         break;
    23                     }
    24                 }
    25             }
    26         }
    27         bool fg = false;
    28         for(int i = A ; i <= B ; ++ i) if(f[i][n]) fg = true;
    29         if(!fg) ans |= 1ll<<l;
    30         else st |= 1ll<<l;
    31     }
    32     return;
    33 }
    34 
    35 int MIN(int A, int B) { return A<B?A:B; }
    36 
    37 void Solve2() {
    38     ll st = 0;
    39     for(int l = lg ; l >= 0 ; -- l) {
    40         memset(g, 0x3f, sizeof(g));
    41         g[0] = 0;
    42         for(int i = 1 ; i <= n ; ++ i) {
    43             for(int j = 0 ; j < i ; ++ j) {
    44                 if(((sum[i]-sum[j])&(st|(1ll<<l)))==0) g[i] = MIN(g[i], g[j]+1);
    45             }
    46         }
    47         bool fg = (g[n]<=B);
    48         if(!fg) ans |= 1ll<<l;
    49         else st |= 1ll<<l;
    50     }
    51     return;
    52 }
    53 
    54 int main() {
    55     freopen("sculpture.in", "r", stdin);
    56     freopen("sculpture.out", "w", stdout);
    57     scanf("%d%d%d", &n, &A, &B);
    58     for(int i = 1 ; i <= n ; ++ i) scanf("%lld", &sum[i]), sum[i] += sum[i-1];
    59     lg = 0;
    60     while((1ll<<lg)<=sum[n]) ++ lg;
    61     if(A>1) Solve1();
    62     else Solve2();
    63     printf("%lld", ans);
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    并查集
    博弈——Bash、Nim、Wythoff
    博弈——SG函数模板
    数据结构——二叉树
    数据结构——链式队列
    sonar-maven-plugin问题
    确立核心模型
    调度思路+EurekaServer获得当前机器的instanceid
    简易的RestClient代码
    Spring Cloud App(Service) Pom示例
  • 原文地址:https://www.cnblogs.com/assassain/p/5440312.html
Copyright © 2011-2022 走看看