【CF】3B Lorry
这道题目网上有几个题解,均有问题。其实就是简单的贪心+排序,没必要做的那么复杂。
一旦tot+curv > v时,显然curv==2, 有三种可能:
(1)取出最小的curv==1的pp,装入当前的p;
(2)取出后续最大的curv==1的p,并且装入;
(3)当前已经是最优的(即后续不存在curv==1的类型),同时前一个的pp比当前的p更优。(这种情况不需要特判)
1 /* 3B */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 typedef struct node_t { 43 int t, p, id; 44 friend bool operator< (const node_t& a, const node_t& b) { 45 if (a.p == b.p) 46 return a.t < b.t; 47 return a.p > b.p; 48 } 49 } node_t; 50 51 const int maxn = 1e5+5; 52 node_t nd[maxn]; 53 54 int main() { 55 ios::sync_with_stdio(false); 56 #ifndef ONLINE_JUDGE 57 freopen("data.in", "r", stdin); 58 freopen("data.out", "w", stdout); 59 #endif 60 61 int n, v; 62 63 scanf("%d %d", &n, &v); 64 rep(i, 1, n+1) { 65 scanf("%d %d", &nd[i].t, &nd[i].p); 66 nd[i].id = i; 67 if (nd[i].t == 1) 68 nd[i].p += nd[i].p; 69 } 70 71 sort(nd+1, nd+1+n); 72 73 int i, j, k, p, pp = 0, pid, tot = 0; 74 int ans = 0, tmp; 75 vi vc; 76 77 i = 1; 78 while (i <= n) { 79 if (nd[i].t == 1) { 80 k = 1; 81 p = nd[i].p>>1; 82 pp = p; 83 pid = nd[i].id; 84 } else { 85 k = 2; 86 p = nd[i].p; 87 } 88 89 if (tot+k <= v) { 90 tot += k; 91 ans += p; 92 vc.pb(nd[i].id); 93 } else if (pp) { 94 // tot+k > v 95 // must be k == 2 96 // and pre has a 1 97 j = i+1; 98 while (j<=n && nd[j].t!=1) 99 ++j; 100 101 // no type 1 but may be pp < p (becase p is half if the nd[pid].p). 102 if (j > n) { 103 tmp = 0; 104 } else { 105 tmp = nd[j].t>>1; 106 } 107 // two way to solve 108 if (p-pp > tmp) { 109 // erase pid and add new id 110 for (vi::iterator iter=vc.begin(); iter!=vc.end(); ++iter) { 111 if (*iter == pid) { 112 vc.erase(iter); 113 break; 114 } 115 } 116 vc.pb(nd[i].id); 117 ans += p-pp; 118 } else if (tmp) { 119 // add nd[j].id; 120 vc.pb(nd[j].id); 121 ans += tmp; 122 } 123 124 break; 125 } 126 127 if (tot == v) 128 break; 129 ++i; 130 } 131 132 printf("%d\n", ans); 133 rep(i, 0, SZ(vc)) { 134 printf("%d ", vc[i]); 135 } 136 putchar('\n'); 137 138 #ifndef ONLINE_JUDGE 139 printf("time = %d.\n", (int)clock()); 140 #endif 141 142 return 0; 143 }