BZOJ 1190: [HNOI2007]梦幻岛宝珠
2016-09-11 20:56
447 查看
关于题意不多说了,根据a*2^b很明显发现可以根据b来进行DP
然后 分b层 f[i][j]表示 j*2^i下获得的最大价值 关于后面的位先不理 我们便可以进行01背包
接着 我们可以发现 如果w的第i位为0 j为1的时候可能装不下,这时如果你想保存这个状态 就需要在前一位-1,大概就是这个意思,自己好好想一想吧,毕竟这里没有口述和白板。
膜拜PoPoQQQ ,
参考抄袭了一下他的简洁代码
其实不建议像我这样打,时间复杂度比较大。。我的代码好像跑的很慢,,,知道思路就好了
然后 分b层 f[i][j]表示 j*2^i下获得的最大价值 关于后面的位先不理 我们便可以进行01背包
接着 我们可以发现 如果w的第i位为0 j为1的时候可能装不下,这时如果你想保存这个状态 就需要在前一位-1,大概就是这个意思,自己好好想一想吧,毕竟这里没有口述和白板。
膜拜PoPoQQQ ,
参考抄袭了一下他的简洁代码
其实不建议像我这样打,时间复杂度比较大。。我的代码好像跑的很慢,,,知道思路就好了
#include<cstdio> #include<cstring> #include<algorithm> #define me(a,x) memset(a,x,sizeof a) using namespace std; int ans,f[35][1010]; int main() { int n,w,i,j,x,k; while(scanf("%d%d",&n,&w)) { if(n<0)break; ans=0; me(f,0); for(i=1;i<=n;i++) { int a,b=0; scanf("%d%d",&a,&x); while(~a&1) a>>=1,b++; for(j=1000;j>=a;j--) f[b][j]=max(f[b][j],f[b][j-a]+x); } for(i=0;i<=30;i++) for(j=1;j<=1000;j++) f[i][j]=max(f[i][j],f[i][j-1]); for(i=1;i<=min(w,1000);i++) ans=max(ans,f[0][i]); for(i=1;i<=30&&(1<<i)<=w;i++) for(j=min(1000,w>>i);j>=0;j--) { int u=(w>>i-1)&1; for(k=0;k<=j;k++) f[i][j]=max(f[i][j],f[i][j-k]+f[i-1][min((k<<1)+u,1000)]); ans=max(ans,f[i][j]); } printf("%d\n",ans); } return 0; }
相关文章推荐
- [bzoj1190][HNOI2007]梦幻岛宝珠 分组背包
- [DP]BZOJ 1190——[HNOI2007]梦幻岛宝珠 动态规划]
- [数位DP] BZOJ1190. [HNOI2007]梦幻岛宝珠
- 1190: [HNOI2007]梦幻岛宝珠 - BZOJ
- BZOJ 1190 HNOI2007 梦幻岛宝珠 动态规划
- 【BZOJ1190】[HNOI2007]梦幻岛宝珠 分层背包DP
- bzoj1190 [HNOI2007]梦幻岛宝珠 ( 二进制分组优化背包DP)
- [BZOJ 1190][HNOI2007]梦幻岛宝珠
- 【bzoj1190】[HNOI2007]梦幻岛宝珠 分层背包dp
- BZOJ 1190: [HNOI2007]梦幻岛宝珠 背包DP
- BZOJ 1190 [HNOI2007]梦幻岛宝珠
- 1190: [HNOI2007]梦幻岛宝珠
- 题解 P3188 【[HNOI2007]梦幻岛宝珠】 DP
- BZOJ 1190 梦幻岛宝珠 [01背包][二进制优化]
- BZOJ 1190 梦幻岛宝珠
- 分层背包 [HNOI2007]梦幻岛宝珠
- 【bzoj1190】[HNOI2007]梦幻岛宝珠 分层背包dp
- [DP 背包] BZOJ 1190 [HNOI2007]梦幻岛宝珠
- bzoj1190 梦幻岛宝珠 动态规划
- BZOJ 1190: [HNOI2007]梦幻岛宝珠