zoukankan      html  css  js  c++  java
  • [HDU2191]多重背包

    多重背包暴力DP为$O(nV^2)$,n为物品个数,V为背包容量,二进制优化复杂度为$O(nVlog V)$。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     4 using namespace std;
     5 
     6 const int N=1010;
     7 int T,n,m,v,w,tot,f[N];
     8 
     9 int main(){
    10     for (scanf("%d",&T); T--; ){
    11         scanf("%d%d",&m,&n);
    12         rep(i,0,m) f[i]=0;
    13         rep(i,1,n){
    14             scanf("%d%d%d",&v,&w,&tot);
    15             for (int j=1; tot>=j; tot-=j,j<<=1)
    16                 for (int k=m; k>=j*v; k--) f[k]=max(f[k],f[k-j*v]+j*w);
    17             if (!tot) continue;
    18             for (int k=m; k>=tot*v; k--) f[k]=max(f[k],f[k-tot*v]+tot*w);
    19         }
    20         printf("%d
    ",f[m]);
    21     }
    22     return 0;
    23 }
    二进制优化

    单调队列优化复杂度为$O(nV)$。

    单调队列的主要思想是从DP方程入手:$$f_{i+j imes v}=max{f_{i+k imes v}+(j-k) imes w}=max{f_{i+k imes v}-k*w}+j*w$$

    v为当前物品的代价,w为价值。j-tot<=k<=j,tot为当前物品的个数。

    发现所有转移都是在同一剩余系下做的,所以只要对每个剩余系分别维护一个单调队列即可。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     4 using namespace std;
     5 
     6 const int N=1010;
     7 int T,n,m,v,w,tot,q1[N],q2[N],f[N];
     8 
     9 void DP(int v,int w,int tot){
    10     for (int i=0; i<v; i++){
    11         int st=0,ed=0; q1[0]=q2[0]=0;//单调队列,q1[]存队列内下标,q2[]存队列内的值
    12         for (int j=0; j<=(m-i)/v; j++){//f[i+j*v[i]]=max{f[i+k*v[i]]+k*w[i]}+j*w[i](j-tot<=k<=j)
    13             if (st<=ed && q1[st]<j-tot) st++;//j-tot<=k<=j
    14             int t=f[i+j*v]-j*w;//队列中存f[i+j*v]-j*w
    15             f[i+j*v]=max(f[i+j*v],q2[st]+j*w);//更新f[i+j*v]
    16             while (st<=ed && t>=q2[ed]) ed--;//将j放入队列
    17             q1[++ed]=j; q2[ed]=t;
    18         }
    19     }
    20 }
    21 
    22 int main(){
    23     freopen("hdu2191.in","r",stdin);
    24     freopen("hdu2191.out","w",stdout);
    25     for (scanf("%d",&T); T--; ){
    26         scanf("%d%d",&m,&n); int mx=0;
    27         rep(i,0,m) f[i]=0;
    28         rep(i,1,n) scanf("%d%d%d",&v,&w,&tot),DP(v,w,tot);
    29         rep(i,1,m) mx=max(mx,f[i]); printf("%d
    ",mx);
    30     }
    31     return 0;
    32 }
  • 相关阅读:
    zipline自制data bundles
    zipline目录结构
    Zipline入门教程
    QuantStart量化交易文集
    如何学习量化投资
    数字货币量化分析报告[2018-02-07]
    用于金融分析的Python包
    时间序列模式——ARIMA模型
    一份数学小白也能读懂的「马尔可夫链蒙特卡洛方法」入门指南
    Python实现HMM(隐马尔可夫模型)
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9552590.html
Copyright © 2011-2022 走看看