[DP] Codeforces Gym 101002 H. Jewel Thief

    xiaoxiao2021-03-25  18

    它是个背包 我们就做背包 因为体积范围很小 我们按体积分类 然后因为当我们决策某个体积拿多少个时肯定拿价值大的前几个 我们按体积划分阶段DP 然后发现转移都是在差为体积整数倍之间 按照容量对体积取模分组 发现组内部转移满足神奇的决策单调性?! 然后就大力分治一发 O(KClogC)

    正解肯定不是这个 正解肯定不是这个 正解肯定不是这个 正解真的不是这个 应该 O(KC)

    #include<cstdio> #include<cstdlib> #include<algorithm> #include<functional> #include<vector> using namespace std; typedef long long ll; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } int n,m,maxc; vector<ll> a[305]; ll f[2][100005]; ll lst[50005],pnt; int x,b,t; inline void Solve(int l,int r,int al,int ar){ if (l>r) return; int i=(l+r)>>1,d=i; f[t^1][i*x+b]=f[t][i*x+b]; for (int j=min(ar,i-1);j>=al;j--){ if (i-j>(int)a[x].size()) break; if (f[t][j*x+b]+a[x][i-j-1]>f[t^1][i*x+b]) f[t^1][i*x+b]=f[t][j*x+b]+a[x][i-j-1],d=j; } Solve(l,i-1,al,d); Solve(i+1,r,d,ar); } int main(){ int _x,_y; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(m); for (int i=1;i<=n;i++) read(_x),read(_y),a[_x].push_back(_y),maxc=max(maxc,_x); for (int i=1;i<=maxc;i++) { sort(a[i].begin(),a[i].end(),greater<int>()); for (int j=1;j<(int)a[i].size();j++) a[i][j]+=a[i][j-1]; } t=0; for (x=1;x<=maxc;x++){ if (a[x].size()==0) continue; for (b=0;b<x;b++){ Solve(0,(m-b)/x,0,(m-b)/x); } for (int j=1;j<=m;j++) f[t^1][j]=max(f[t^1][j],f[t^1][j-1]); t^=1; } for (int i=1;i<=m;i++) printf("%I64d%c",f[t][i],i==m?'\n':' '); return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-300251.html

    最新回复(0)