Gym - 101002H: Jewel Thief (背包,分组,DP决策单调性)

pro:给定N,M。输入N个物品,(si,vi)表示第i个物品体积为si,价值为vi,s<=300,vi<=1e9; N<1e6;现在要求,对于背包体积为1到M时,求出最大背包价值。

sol:显然直接跑背包会爆炸。 发现物品体积都比较小,我们先对相同体积的排序,对于体积相同的一起处理。

然后发现转移都是在差为体积整数倍之间,按照容量对体积取模分组 ,发现组内部转移满足神奇的决策单调性。 然后就是s次分治。

O(KClogC)

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep2(i,a,b) for(int i=b;i>=a;i--)
using namespace std;
const int maxn=310;
const int maxm=100010;
ll dp[2][maxm];
vector<ll>G[maxn]; int x,d,t;
void get(int L,int R,int l,int r)
{
    if(L>R) return ;
    int Mid=(L+R)>>1,pos=Mid;
    for(int i=min(r,Mid-1);i>=l;i--){
        if(Mid-i>G[x].size()) break;
        if(dp[t][d+Mid*x]<dp[t^1][d+i*x]+G[x][Mid-i-1]){
            pos=i; dp[t][d+Mid*x]=dp[t^1][d+i*x]+G[x][Mid-i-1];
        }
    }
    get(L,Mid-1,l,pos);
    get(Mid+1,R,pos,r);
}
int main()
{
    int N,M,s;ll v;
    scanf("%d%d",&N,&M);
    rep(i,1,N){
        scanf("%d%lld",&s,&v);
        G[s].push_back(v);
    }
    rep(i,1,300){
        if(G[i].size()==0) continue;
        sort(G[i].begin(),G[i].end(),greater<int>() );
        for(int j=1;j<G[i].size();j++) G[i][j]+=G[i][j-1];
        t^=1;  rep(j,1,M) dp[t][j]=dp[t^1][j];
        rep(j,0,i-1){
            d=j;  x=i;
            get(0,(M-j)/i,0,(M-j)/i);
        }
        rep(j,1,M) dp[t][j]=max(dp[t][j],dp[t][j-1]);
    }
    rep(i,1,M) printf("%lld ",dp[t][i]);
    return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/10546963.html

时间: 2024-08-30 13:30:01

Gym - 101002H: Jewel Thief (背包,分组,DP决策单调性)的相关文章

bzoj 4899 记忆的轮廓 题解(概率dp+决策单调性优化)

题目背景 四次死亡轮回后,昴终于到达了贤者之塔,当代贤者夏乌拉一见到昴就上前抱住了昴“师傅!你终于回来了!你有着和师傅一样的魔女的余香,肯定是师傅”.众所周知,大贤者是嫉妒魔女沙提拉的老公,400年前与神龙.剑圣一起封印魔女因子暴走的莎缇拉.在魔女茶会的时候,莎缇拉也表示过对昴浓浓的爱意,昴便是被莎缇拉召唤来异世界的.而贤者之塔中的资料与试炼,似乎都指向同一种可能性……记忆的轮廓,逐渐显形…… 题目描述 通往贤者之塔的路上,有许多的危机.我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编

题解——[NOI2009]诗人小G 决策单调性优化DP

第一次写这种二分来优化决策单调性的问题.... 调了好久,,,各种细节问题 显然有DP方程: f[i]=min(f[j] + qpow(abs(sum[i] - sum[j] - L - 1))); 其中f[i]代表到了第i个句子的最小答案 qpow用于处理^p sum为前缀和 (同时为了处理句子之间的空格问题,我们在统计前缀和的时候就默认在句子后面加一个空格, 然后在计算的时候,由于每一行只有最后一个不用加空格,直接减掉这个多加的空格即可获得正确长度) 首先我们可以打表发现是满足决策单调性的,

hdu 1011 Starship Troopers (依赖背包 树形dp)

题目: 链接:点击打开链接 题意: n个房间组成一棵树,你有m个战队,从1号房间开始依次clear每个房间,在每个房间需要花费的战队个数是bugs/20,得到的价值是the possibility of capturing a brain,求最大的价值. 算法: 树形dp,有依赖的背包问题.(依次clear每个房间) 思路: 状态转移dp[i][j]表示根结点为i时(房间i)花费j个战队能够得到的最大价值(捕捉到一个brain最大的可能值).递归求出每个根结点处的最大值,最后dp[1][m]就是

!HDU 1024 Max Sum Plus Plus-dp-(分组dp?最大分段子序列和)

题意:n个数,分成m段,求这m段的最大和,段之间不能交叉. 分析: 这题跟最大子序列和的区别在于要求分成m段,所以做法就千差万别了.实际的做法倒有点像分组dp(将n个数分成m组),但是本题与上次写的两道分组dp(搬寝室和特殊的筷子)的不同是:上两题每组选两or三个元素,本题不确定每一段要选多少个元素:上两题先排序再做,这题只能根据序列原定顺序走. 本题难点: 1.状态:dp[i][j]在确定选第j个元素的前提下,前j个分i段的最大和:所有对于j号元素有两种情况:1).加入已经确定的i段中最后一段

DP + 斜率优化 / 决策单调性 --- [HNOI2008]玩具装箱TOY

[HNOI2008]玩具装箱TOY 题目描述: P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京. 他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中. P教授有编号为\(1......N\)的\(N\)件玩具,第\(i\)件玩具经过压缩后变成一维长度为\(C_{i}\). 为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的. 同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物, 形式地说如果将第\(i\)件玩

决策单调性优化dp

决策单调性: 对于一些dp方程,经过一系列的猜想和证明,可以得出,所有取的最优解的转移点(即决策点)位置是单调递增的. 即:假设f[i]=min(f[j]+b[j]) (j<i) 并且,对于任意f[i]的决策点g[i],总有f[i+1]的决策点g[i+1]>=g[i](或者<=g[i]) 那么,这个方程就具备决策单调性. 这个有什么用吗? 不懂具体优化方法的话确实也没有什么用.可能还是n^2的.只不过范围可能少了一些. 经典入门例题: Description: [POI2011]Ligh

Codeforces 868F. Yet Another Minimization Problem【决策单调性优化DP】【分治】【莫队】

LINK 题目大意 给你一个序列分成k段 每一段的代价是满足\((a_i=a_j)\)的无序数对\((i,j)\)的个数 求最小的代价 思路 首先有一个暴力dp的思路是\(dp_{i,k}=min(dp_{j,k}+calc(j+1,i))\) 然后看看怎么优化 证明一下这个DP的决策单调性: trz说可以冥想一下是对的就可以 所以我就不证了 (其实就是决策点向左移动一定不会更优) 然后就分治记录当前的处理区间和决策区间就可以啦 //Author: dream_maker #include<bi

决策单调性优化dp 专题练习

决策单调性优化dp 专题练习 优化方法总结 一.斜率优化 对于形如 \(dp[i]=dp[j]+(i-j)*(i-j)\)类型的转移方程,维护一个上凸包或者下凸包,找到切点快速求解 技法: 1.单调队列 : 在保证插入和查询的x坐标均具有单调性时可以使用 2.单调栈+二分:保证插入有单调性,不保证查询有单调性 3.分治+ 1 或 2:在每次分治时将\([l,mid]\)这段区间排序后插入,然后更新右区间\([mid+1,r]\)的答案 二.分治.单调队列维护有单调性的转移 (甚至还有分治套分治)

Bzoj 1563: [NOI2009]诗人小G(决策单调性优化)

原题面 带有详细证明的转这里 题意:每一个线段有一个长度,有一个标准长,现在要把这些线段按照顺序分行,每行的不和谐值等于标准长和该行线段总长的差的绝对值的p次方.现在要求最小的不和谐值之和. 开始的时候完全读错题了,以为p==2 for ever.真是太天真.后来看数据范围才发现.我真是面向数据编程? n^2的dp是一眼秒的.然后如果是p=2,那就是一个非常像玩具装箱的斜率优化dp.对于4.5的数据范围.可以想到用贪心优化dp.因为每一行的长度不会通过拼接线段(线段条数>=2)达到2*标准长,这