atcoder#073D(枚舉)
題目鏈接: http://arc073.contest.atcoder.jp/tasks/arc073_b
題意: 給出n, m兩個數, n是物品數目, m是背包容量, 接下來n行輸入, wi, vi分別爲第 i 件物品的體積和價值, 其中 w1 <= wi <= w1+3, 求背包所裝物品的最大價值;
思路: 咋一看是到01背包, 但是m爲1e9, 按一般01背包寫法時間復雜度爲O(n*m), 肯定tle;
這題和一般01背包還有一個不同的地方是 w1 <= wi <= w1+3, 那麼不難想到可以將物品根據 w 值分爲4類;
顯然可以直接枚舉每類物品取了多少個, 然後取sum(vi)最大值即爲答案;
注意:對於同類物品先取vi大的, 貪心嘛...
代碼:
1 #include <iostream> 2 #include <algorithm> 3 #define ll long long 4 using namespace std; 5 6 const int MAXN=1e2+10; 7 ll a[MAXN], b[MAXN], c[MAXN], d[MAXN]; 8 ll av[MAXN], bv[MAXN], cv[MAXN], dv[MAXN]; 9 10 bool cmp(ll a, ll b){ 11 return a>b; 12 } 13 14 int main(void){ 15 ll n, m, x, y, cnt, ans=0; 16 int indxa=1, indxb=1, indxc=1, indxd=1; 17 cin >> n >> m; 18 cin >> x >> y; 19 cnt=x; 20 a[indxa++]=y; 21 for(int i=0; i<n-1; i++){ 22 cin >> x >> y; 23 int cc=x-cnt; 24 if(cc==0) a[indxa++]=y; 25 else if(cc==1) b[indxb++]=y; 26 else if(cc==2) c[indxc++]=y; 27 else d[indxd++]=y; 28 } 29 sort(a+1, a+indxa, cmp); 30 sort(b+1, b+indxb, cmp); 31 sort(c+1, c+indxc, cmp); 32 sort(d+1, d+indxd, cmp); 33 for(int i=1; i<indxa; i++){ 34 av[i]=av[i-1]+a[i]; 35 } 36 for(int i=1; i<indxb; i++){ 37 bv[i]=bv[i-1]+b[i]; 38 } 39 for(int i=1; i<indxc; i++){ 40 cv[i]=cv[i-1]+c[i]; 41 } 42 for(int i=1; i<indxd; i++){ 43 dv[i]=dv[i-1]+d[i]; 44 } 45 for(int i=0; i<indxa; i++){ 46 ll cnt1=i*cnt; 47 if(cnt1>m) break; 48 for(int j=0; j<indxb; j++){ 49 ll cnt2=cnt1+j*(cnt+1); 50 if(cnt2>m) break; 51 for(int k=0; k<indxc; k++){ 52 ll cnt3=cnt2+k*(cnt+2); 53 if(cnt3>m) break; 54 for(int l=0; l<indxd; l++){ 55 ll cnt4=cnt3+(cnt+3)*l; 56 if(cnt4>m) break; 57 ll num=av[i]+bv[j]+cv[k]+dv[l]; 58 ans=max(ans, num); 59 } 60 } 61 } 62 } 63 cout << ans << endl; 64 return 0; 65 }
我就是我,颜色不一样的烟火 --- geloutingyu