NOIP2006提高组第二题-金明的预算方案
作者:互联网
题意:背包问题,每个物品有价值和所谓的重要度,以及可以是其他物品的附件,只有购买了主件才能购买附件,.求有n元买m件以内的物品的最大价值和重要度乘积的和.其中一个主件的附件数比较少,最多只有2个附件.
分析:数据范围比较小,最多只有2个附件直接分组背包,m件是典型二维费用背包,注意枚举顺序是先分组再枚举二个维度最后再枚举组内的物品.
附上自己乱写的常数大的一批的丑b代码:
1 #pragma GCC optimize(2) 2 #include <cstdio> 3 #include <iostream> 4 #include <cstring> 5 #include <cstdlib> 6 #include <vector> 7 #include <map> 8 #include <set> 9 #include <queue> 10 #include <deque> 11 #include <list> 12 #include <climits> 13 #include <bitset> 14 #include <fstream> 15 #include <algorithm> 16 #include <functional> 17 #include <stack> 18 #include <string> 19 #include <cmath> 20 #define fi first 21 #define se second 22 #define re register 23 #define ls i << 1 24 #define rs i << 1 | 1 25 #define pb push_back 26 #define mp make_pair 27 #define pii pair<int,int> 28 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 29 #define mod 1000000007 30 31 //#define int long long 32 33 using namespace std; 34 const double eps = 1e-8; 35 const int inf = 0x3f3f3f3f; 36 const long long INF = 0x3f3f3f3f3f3f3f3f; 37 const double pi = acos(-1.0); 38 39 inline int rd(){ 40 re int res = 0,flag = 0;char ch; 41 if ((ch = getchar()) == '-')flag = 1; 42 else if(ch >= '0' && ch <= '9')res = ch - '0'; 43 while ((ch = getchar()) >= '0' && ch <= '9')res = (res<<1) + (res<<3) + (ch - '0'); 44 return flag ? -res : res; 45 } 46 47 void out(int a) { 48 if (a < 0) { 49 putchar('-');a = -a; 50 } 51 if (a >= 10) out(a / 10); 52 putchar(a % 10 + '0'); 53 } 54 55 const int maxn = 4e4+10; 56 const int maxm = 100; 57 int n, m; 58 int f[maxn][maxm]; 59 60 struct thing{ 61 int val, v, m, id, q; 62 bool friend operator<(const thing &a, const thing &b) { 63 return a.q < b.q; 64 } 65 }; 66 67 vector<thing> goods,e[maxm]; 68 69 //二维费用: 1.价值 2.数量 70 //求最大收益: 价值 * 重要度 71 72 //signed main(){ 73 int main() { 74 n = rd(), m = rd(); 75 for (int i = 1; i <= m; i++) { 76 int v = rd(), p = rd(), q = rd(); 77 goods.pb({v*p, v, 1, i, q}); 78 } 79 sort(goods.begin(), goods.end()); 80 for (int i = 0; i < goods.size(); i++) { 81 if (goods[i].q == 0) e[goods[i].id].pb({goods[i].val, goods[i].v, 1}); 82 else { 83 int now = goods[i].q; 84 int len = e[now].size(); 85 for (int j = 0; j < len; j++) { 86 e[now].pb({e[now][j].val + goods[i].val, e[now][j].v + goods[i].v, e[now][j].m + 1}); 87 } 88 } 89 } 90 for (int i = 1; i <= m; i++) {//分组 91 if (e[i].size() == 0) continue; 92 for (int k = n; k >= 0; k--) {//第一维费用 93 for (int j = m; j >= 0; j--) {//第二维费用 94 for (int s = 0; s < e[i].size(); s++) //枚举组内物品 95 if (k >= e[i][s].v && j >= e[i][s].m) 96 f[k][j] = max(f[k][j], f[k-e[i][s].v][j-e[i][s].m] + e[i][s].val); 97 } 98 } 99 } 100 out(f[n][m]); 101 return 0; 102 }
标签:10,NOIP2006,ch,const,int,金明,预算,include,define 来源: https://www.cnblogs.com/hznudreamer/p/13236754.html