[bzoj1190]梦幻岛宝珠

根据$2^b$分组,组内处理出g[i][j]表示当容量为$j\cdot 2^{i}$且只能选b=i时最大价值,再组间dp用f[i][j]表示当容量为$j\cdot 2^{i}+(w\&(2^{i}-1))$且只能选$b<=i$时的最大价值(j的范围只有$\sum_{i=1}^{n}ai$,即使所有b都在一起也不会超过)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,a,b,v,g[35][1005],f[35][1005];
 4 int main(){
 5     while (scanf("%d%d",&n,&m)!=EOF){
 6         if ((n<0)&&(m<0))return 0;
 7         memset(g,0,sizeof(g));
 8         memset(f,0,sizeof(f));
 9         for(int i=1;i<=n;i++){
10             scanf("%d%d",&a,&v);
11             b=0;
12             while (a%2==0){
13                 a/=2;
14                 b++;
15             }
16             for(int j=1000;j>=a;j--)g[b][j]=max(g[b][j],g[b][j-a]+v);
17         }
18         memcpy(f[0],g[0],sizeof(g[0]));
19         for(int i=1;i<=30;i++){
20             int p=((m>>i-1)&1);
21             for(int j=1000;j>=0;j--)
22                 for(int k=1000-p;k>=0;k-=2){
23                     int l=j+(k-p>>1);
24                     if (l<=1000)f[i][l]=max(f[i][l],f[i-1][k]+g[i][j]);
25                 }
26         }
27         printf("%d\n",f[30][0]);
28     }
29 }
View Code

 

posted @ 2019-08-16 08:45  PYWBKTDA  阅读(124)  评论(0编辑  收藏  举报