洛谷3188
显然是DP
将
设
设当前DP到的这个物品的系数为
考虑合并
设
此时对于当前DP到的这个种类系数一定不能取超过
那么有
将
最终的答案为
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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .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语句:使用策略模式优化代码结构