码迷,mamicode.com
首页 > 其他好文 > 详细

UOJ370 滑稽树上滑稽果 【状压DP】

时间:2018-07-07 20:10:53      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:gis   其它   题目   work   ret   影响   方案   printf   span   

题目分析:

答案肯定是链,否则可以把枝干放到主干。

去除一直存在的位,这样0位占满时就会结束。

用$f[S]$表示0位填埋情况,每次转移是它的一个子集,我们考虑可否转移。

再用$g[S]$存储转移是否合法,用滑稽果填充$g$数组。不一定要完全满足条件,因为有其它方案更优,无影响。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define RI register
 5 
 6 const int maxn = 202000;
 7 
 8 int n,a[maxn],bit=1,maxx;
 9 long long ans = 0;
10 int cnt = (1<<18)-1,res=0;
11 
12 int f[1<<18];
13 int g[1<<18],vol[1<<18];
14 char buffer[20000000], *buf=buffer;
15 inline void in(int &x) {
16     while(*buf>9 || *buf<0) ++buf;
17     for(x=0;*buf>=0&&*buf<=9; ++buf) x=x*10+*buf-0;
18 }
19 
20 inline void read(){
21     in(n);
22     for(RI int i=1;i<=n;i++) in(a[i]),cnt &= a[i];
23     for(RI int i=1;i<=n;i++) a[i] -= cnt,maxx=max(maxx,a[i]),res |= a[i];
24     ans += 1ll*cnt*n;
25 }
26 
27 inline void init(){
28     while((bit<<1)<=maxx)bit<<=1; bit<<=1; res = (bit-1-res);
29     for(RI int i=1;i<=n;i++) vol[bit-1-a[i]]=1;
30     for(RI int i=bit-1;i>=0;i--){
31     if(!vol[i] || g[i]) continue;
32     for(RI int j=i;j;j=((j-1)&i)){g[j]=1;}
33     }
34 }
35 
36 inline void work(){
37     memset(f,0x3f,sizeof(f)); f[0] = 0;
38     for(RI int now=0;now<bit;now++){
39     if(f[now] > 1e6) continue;
40     int dt = bit-1-now;
41     for(RI int i=dt;i;i=((i-1)&dt)){
42         if(g[i]){f[now+i] = min(f[now+i],f[now]+bit-1-(now+i));};
43     }
44     }
45     ans += f[bit-1];
46     printf("%lld",ans);
47 }
48 
49 int main(){
50     fread(buffer, 1, (sizeof buffer)-1, stdin);
51     read();
52     init();
53     work();
54     return 0;
55 }

 

UOJ370 滑稽树上滑稽果 【状压DP】

标签:gis   其它   题目   work   ret   影响   方案   printf   span   

原文地址:https://www.cnblogs.com/Menhera/p/9277639.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!