雅礼集训2017 珠宝
这题看题面发现这是一个标准的背包,尝试寻找突破口,突然发现,所以考虑把相同的珠宝放在一起转移
对于同一个代价的物品肯定是优先选择价值较大的,于是我们把同代价的物品按照价值从大到小排序,并且累计前缀和,这些每次会选一些点,很容易可以想到这个选点具有决策单调性
然后是用分治(即应用决策单调性)优化dp
点击查看代码
//CAN'T FORGET
//CAN'T FORGET
//CAN'T FORGET
//#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define _ 0
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
vector<long long> g[305];
long long dp[305][maxn];
int a[maxn],nm;
void solve(int l,int r,int L,int R,int x)
{
if(l>r)
return ;
int mid=(l+r)>>1,pos=L;
for(int i=max(L,mid-(int)g[x].size());i<=min(mid,R);i++)
{
long long w;
if(i==mid)
w=0;
else
w=g[x][mid-i-1];
if(dp[x][a[mid]]<dp[x-1][a[i]]+w)
{
dp[x][a[mid]]=dp[x-1][a[i]]+w;
pos=i;
}
}
solve(l,mid-1,L,pos,x);
solve(mid+1,r,pos,R,x);
}
bool cmp(int x,int y)
{
return x>y;
}
int main(){
freopen("jewelry.in","r",stdin);
freopen("jewelry.out","w",stdout);
int n=read(),m=read();
int maxv=0;
for(int i=1;i<=n;i++)
{
int c=read(),v=read();
maxv=max(maxv,c);
g[c].push_back(v);
}
for(int i=1;i<=maxv;i++)
{
sort(g[i].begin(),g[i].end(),cmp);
for(int j=1;j<g[i].size();j++)
g[i][j]+=g[i][j-1];
}
for(int i=1;i<=maxv;i++)
{
for(int j=0;j<=i-1;j++)
{
nm=0;
for(int k=j;k<=m;k+=i)
a[++nm]=k;
solve(1,nm,1,nm,i);
}
}
for(int i=1;i<=m;i++)
cout<<dp[maxv][i]<<" ";
cout<<endl;
return ~~(0^_^0);
}
/*
Notes:
1.看所有题目
2.注意数据范围
3.想想自己还能做什么而不是做了什么
4.看清题目!!!
5.记得把调试代码删掉!!!!
6.longlong时 1要写成1ll
7.Think twice code once, think once code forever!
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现