很经典的贪心。
思路:这题如果用DP的话,会超内存并且很难记录是那些点。开两个数组,一个记录type 1的,一个记录type 2的。然后都排序,然后逐个累加。
比如test3:
10 10 1 14 2 15 2 11 2 12 2 9 1 14 2 15 1 9 2 11 2 6分开排序后:
1 14
1 14
1 9
2 15
2 15
2 12
2 11
2 11
2 9
2 6
然后累加后:
第一个数组:14(1)28(2)37(3)
第二个数组:15(1)30(2)42(3)53(4)64(5)73(6)79(7)
而容积10就可以看成是第一个数组和第二个数组的匹配了。
这道题坑爹的是输出。反正思路是对了~输出就自己yy了~
#include <iostream> #include <algorithm> #include <stdio.h> using namespace std; struct B { int c,id; }p1[100010],p2[100010]; int s1[100010],s2[100010]; bool cmp(B a,B b) { return a.c > b.c; } int main() { int n,v,i,k1,k2,t,loc1,loc2,vv,ans,c,k; //freopen("a.txt","r",stdin); int s[100010]; while(cin>>n>>v) { ans = 0;k = 0; //for(i = 0;i < ) for(i = 0,k1 = 1,k2 = 1;i < n;i ++) { cin>>t>>c; if(t == 1) {p1[k1].c = c;p1[k1].id = i+1;k1++;} else {p2[k2].c = c;p2[k2].id = i+1;k2++;} } s1[0] = 0;s2[0] = 0; sort(p1+1,p1+k1+1,cmp); sort(p2+1,p2+k2+1,cmp); s1[1] = p1[1].c;s2[1]=p2[1].c; for(i = 2;i <= k1;i ++) s1[i] = s1[i-1] + p1[i].c; for(i = 2;i <= k2;i ++) s2[i] = s2[i-1] + p2[i].c; for(i = 0;i <= k1;i ++) { if(i <= v) { vv = v - i; if(vv > 2*k2) vv = 2*k2; if(vv % 2 == 1) vv --; vv /= 2; if(s1[i]+s2[vv] > ans) { ans = s1[i]+s2[vv]; loc1 = i;loc2 = vv; } } } cout<<ans<<endl; //cout<<loc1<<" "<<loc2<<endl; //cout<<k1<<" "<<k2<<endl; for(i = 1;i <= loc1&&i <= k1-1;i ++) s[k++] = p1[i].id; for(i = 1;i <= loc2&&i <=k2-1;i ++) s[k++] = p2[i].id; if(k > 0){ cout<<s[0]; for(i = 1;i < k;i ++) cout<<" "<<s[i]; cout<<endl; } else continue; } }