描述 Description
MM 虽然一辈子只要一个,但是也得早点解决。于是,n 个光棍们自发组成了一个光棍组织
(ruffian organization,By Wind 乱译)。现在,光棍们打算分成几个小组,并且分头为 找 MM 事业做贡献(For example:searching,hunting……By Wind 乱译)。
对于这 n 个光棍的任意一个组合,都有一个被称为“和谐度”的东西,现在,他们想知道, 如何分组可以使和谐度总和最大。
每个光棍都必须属于某个分组,可以一个人一组。
【题解】
传送门(sro_chadLZX_orz):http://www.cnblogs.com/chadinblog/p/5882605.html
我把他的记忆化搜索写成了递推形式
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<ctime> 7 #include<algorithm> 8 using namespace std; 9 int n,a[1000100],f[1000100]; 10 inline int read() 11 { 12 int x=0,f=1; char ch=getchar(); 13 while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} 14 while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} 15 return x*f; 16 } 17 void dp() 18 { 19 for(int i=1;i<=(1<<n)-1;i++) 20 { 21 int x=i&(-i),y=i&(~x); 22 for(int j=0;;) 23 { 24 f[i]=max(f[i],f[y-j]+a[x|j]); 25 j=((j|(~y))+1)&y; 26 if(j==0) break; 27 } 28 } 29 printf("%d ",f[(1<<n)-1]); 30 } 31 int main() 32 { 33 //freopen("cin.in","r",stdin); 34 //freopen("cout.out","w",stdout); 35 n=read(); 36 for(int i=1;i<=(1<<n)-1;i++) a[i]=read(); 37 dp(); 38 return 0; 39 }