codevs5429 多重背包【多重背包+单调队列】
生活随笔
收集整理的這篇文章主要介紹了
codevs5429 多重背包【多重背包+单调队列】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
5429 多重背包
時間限制: 1 s
空間限制: 256000 KB
題目等級 : 鉆石 Diamond
題目描述 Description
你有一個容量為M的背包,和N種物品。
每種物品都有三個屬性,vi,wi,與ci,分別表示這種物品的體積、價值和件數。
你的任務是,從這些所給物品中,選出若干件,其體積之和不能超過背包容量,并且使所選物品的權值的和最大。
輸入描述 Input Description
第一行兩個整數N,M
接下來N行每行三個數vi,wi,ci描述第i件物品的屬性
輸出描述 Output Description
最大的權值和
樣例輸入 Sample Input
2 8
2 100 4
4 100 2
樣例輸出 Sample Output
400
數據范圍及提示 Data Size & Hint
對于20%的數據,ci=1
對于60%的數據,N,M<=500,ci<=100
對于90%的數據,N,M<=3000
對于100%的數據,N,M<=7000,ci<=5000,保證答案不超過2147483647
解題思路:
此題若直接使用多重背包的版子會超時,需通過單調隊列將其優化。
代碼:
#include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <cstdlib> #include <cstring> #include <map> #include <stack> #include <queue> #include <vector> #include <bitset> #include <set> #include <utility> #include <sstream> #include <iomanip> using namespace std; typedef long long ll; typedef unsigned long long ull; #define inf 0x3f3f3f3f #define rep(i,l,r) for(int i=l;i<=r;i++) #define lep(i,l,r) for(int i=l;i>=r;i--) #define ms(arr) memset(arr,0,sizeof(arr)) //priority_queue<int,vector<int> ,greater<int> >q; const int maxn = (int)1e5 + 5; const ll mod = 1e9+7; int vi[7500],wi[7500],ci[7500]; int dp[7500]; typedef pair<int,int> p; deque<p> qu; int main() {#ifndef ONLINE_JUDGE//freopen("in.txt", "r", stdin);#endif//freopen("out.txt", "w", stdout);//ios::sync_with_stdio(0),cin.tie(0);int N,M;scanf("%d %d",&N,&M);rep(i,1,N) scanf("%d %d %d",&vi[i],&wi[i],&ci[i]);for(int i=1;i<=N;i++) {int v=vi[i],w=wi[i],c=ci[i];for(int d=0;d<v;d++) {while(!qu.empty()) qu.pop_back();for(int j=0;j<=(M-d)/v;j++) {if(j-qu.front().first>c) qu.pop_front();while(!qu.empty()&&dp[j*v+d]-j*w>=qu.back().second)qu.pop_back();qu.push_back(p(j,dp[j*v+d]-j*w));dp[j*v+d]=qu.front().second+j*w;}}}printf("%d\n",dp[M]);return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的codevs5429 多重背包【多重背包+单调队列】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MIP 官方发布 v1稳定版本
- 下一篇: Problem A: 删除区间内的元素(