洛谷 P1858 多人背包 DP
阿新 • • 發佈:2018-10-19
lse for bit 輸入輸出 輸入 pri 背包 toc turn
目錄
- 題面
- 題目鏈接
- 題目描述
- 輸入輸出格式
- 輸入格式
- 輸出格式
- 輸入輸出樣例
- 輸入樣例
- 輸出樣例
- 說明
- 思路
- AC代碼
題面
題目鏈接
洛谷 P1858 多人背包
題目描述
求01背包前k優解的價值和
輸入輸出格式
輸入格式
第一行三個數 $ K,V,N $
接下來每行兩個數,表示體積和價值
輸出格式
前 $ k $ 優解的價值和
輸入輸出樣例
輸入樣例
2 10 5
3 12
7 20
2 4
5 6
1 1
輸出樣例
57
說明
對於100%的數據, $ K \leq 50,V \leq 5000,N \leq 200 $
【時空限制】
1000ms,128MB
思路
求k優解。可以考慮開二維數組f[v][k],表示裝v體積物品的第k優解
加入每一件物品時,就要更新f[V]到f[v[i]]的值。對於新的f[v],應該是當前的f[v]與f[v-v[i]]+w[i]合並後的序列,取其中前k優就好了
AC代碼
#include<bits/stdc++.h> const int maxk=60; const int maxn=210; const int maxv=5010; using namespace std; int k,V,n; int v[maxn],w[maxn]; int f[maxv][maxk]; int ans; int main() { scanf("%d%d%d",&k,&V,&n); for(int i=1;i<=n;i++) scanf("%d%d",&v[i],&w[i]); for(int i=0;i<=V;i++) for(int j=0;j<=k;j++) f[i][j]=-100000; f[0][1]=0; for(int i=1;i<=n;i++) { for(int j=V;j>=v[i];j--) { int p1=1,p2=1,tmp[maxk]; while(p1+p2-1<=k) { if(f[j][p1]>f[j-v[i]][p2]+w[i]) tmp[p1+p2-1]=f[j][p1],p1++; else tmp[p1+p2-1]=f[j-v[i]][p2]+w[i],p2++; } for(int t=1;t<=k;t++) f[j][t]=tmp[t]; } } for(int t=1;t<=k;t++) ans+=f[V][t]; printf("%d",ans); return 0; }
洛谷 P1858 多人背包 DP