P16160 [ICPC 2016 NAIPC] Jewel Thief
首先直接
但是
然后就是 P1776 经典转化,发现
难以优化,想了很久想试试是不是有决策单调性,于是挂了个拍看看是不是对的。跑了大概十万组后好像猜到决策是单调不降的,然后试着推了推。
设
此时
非同层转移,分治或者是简化 LARSCH 算法优化做到
这里的代码是分治的。
::::success[代码]
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int R=305,N=1e6+5,M=1e5+5;
ll s[N],f[M],g[M];vector<int>Q[R];
void solve(int w,int d,int l,int r,int L,int R)
{
int opt=L,i=(l+r)>>1;
for(int j=L;j<=min(R,i);j++)
{
if(i-j>Q[w].size())continue;
if(f[i*w+d]<=g[j*w+d]+s[i-j])
{
f[i*w+d]=g[j*w+d]+s[i-j];
opt=j;
}
}
if(l<i)solve(w,d,l,i-1,L,opt);
if(r>i)solve(w,d,i+1,r,opt,R);
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
int w,v;
scanf("%d%d",&w,&v);
Q[w].emplace_back(v);
}
for(int w=1;w<=min(k,300);w++)
{
if(Q[w].empty())continue;
sort(begin(Q[w]),end(Q[w]),greater<ll>());
for(int i=1;i<=Q[w].size();i++)s[i]=s[i-1]+Q[w][i-1];
for(int r=0;r<w;r++)solve(w,r,0,(k-r)/w,0,(k-r)/w);
memcpy(g,f,sizeof(f));
}
for(int i=1;i<=k;i++)printf("%lld ",f[i]);
return 0;
}
::::