洛谷3188

显然是DP
a×2bb相同的分成一类
f[i][j]表示2的指数为i时,前面的系数为j(即总的重量为j×2i)时的最大价值
设当前DP到的这个物品的系数为k,有f[i][j]=max(f[i][j],f[i][jk]+val)
考虑合并
g[i][j]表示当前DP到的种类(即2的次幂)为i,背包总容量为j×2i+W&((1<<i)1)(即W的后i位)时的最大价值
此时对于当前DP到的这个种类系数一定不能取超过j+1,因为显然有(j+1)×2ij×2i+W&((1<<i)1)
那么有g[i][j]=max(g[i][j]f[i][k]+g[i1][2j2k+((W>>i1)&1)])(0kj)
j×2i+W&((1<<i)1)k×2i变形即可得到以上式子
最终的答案为g[31][0]

code(由于用了vector,常数过大)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+10,M=3e5+10;
int n;
ll W;
ll f[32][1010],g[32][1010];
struct Node
{
	int num;
	ll val;
}temp;
vector<Node> obj[32];
int read()
{
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-f;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-48;s=getchar();}
    return x*f;
}
int main()
{
	do
	{
		n=read(),W=read();
		if(n==-1&&W==-1) break;
		for(int i=0;i<=30;i++) obj[i].clear();
		memset(f,0,sizeof(f));
		memset(g,0,sizeof(g));
		for(int i=1,w,v;i<=n;i++)
		{
			w=read(),v=read();
			int cnt=0;
			while(!(w&1))
			{
				w>>=1;
				cnt++;
			}
			temp.num=w,temp.val=v;
			obj[cnt].push_back(temp);
		}
		for(int i=0;i<=30;i++)
		for(int j=0;j<obj[i].size();j++)
		for(int k=min(W/(1LL<<i),(ll)10*n);k>=obj[i][j].num;k--)
		f[i][k]=max(f[i][k],f[i][k-obj[i][j].num]+obj[i][j].val);
		for(int j=0;j<=10*n;j++) g[0][j]=f[0][j];
		for(int i=1;i<=31;i++)
		for(int j=min((ll)10*n,W/(1LL<<i));j>=0;j--)
		for(int k=0;k<=j;k++)
		g[i][j]=max(g[i][j],f[i][k]+g[i-1][(j-k<<1)+((W>>i-1)&1)]);
		printf("%lld\n",g[31][0]);
	}while(1);
	return 0;
}
posted @   最爱丁珰  阅读(33)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示