hdu 2191 (多重背包的单调队列优化)

  多重背包单调队列优化是思想是。普通的dp为

dp[i][j]=max{dp[i-1][j-k*v[i]]+k*w[i]};

其实你可以发现对能更新j是j和一个剩余类。也就是 

0, v[i],2v[i],3v[i] ,4v[i]...

1 ,1+v[i],1+2v[i],1+3v[i]

...........

v[i]-1,2*v[i]-1......

更新值存在一个剩余类中,组与组之间不存在更新。那么实际上我们可以写dp写好这样

dp[b+x*v[i]]=max{ dp[b+k*v[i]]+(x-k)*w[i] }=max{dp[b+k*v[i]]-k*w[i]}+x*w[i] ;  (x-c[i]<=k && k<=x)

实际上一个j对于一个x和b,那么可以看出实际上就是几率一段x之前的c[i]区间内的最值。这是一个很明显的单调队列优化。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef __int64 LL;
const int mmax  = 1000010;
const int inf = 0x3fffffff;
int p[110],h[110],c[110];
int dp[110][110];
int Q[110];
int head,tail;
void add(int b,int i,int k)
{
    while(head>T;
    while(T--)
    {
        scanf("%d %d",&n,&m);
        for(int i=1;i<=m;i++)
            scanf("%d %d %d",&p[i],&h[i],&c[i]);
        memset(dp,0,sizeof dp);
        for(int i=1;i<=m;i++)
        {
            for(int j=0;j


你可能感兴趣的:(Dp)