• 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 }

     积累:

       yxc:所有的背包问题都是先循环物品再循环体积再循环决策.

  • 相关阅读:
    stack 栈
    链表
    2018.09.08 DL24 Day1 总结
    10.07 WZZX Day2总结
    10.06 WZZX Day1总结
    Joseph问题 (线段树)
    [POI2006]TET-Tetris 3D
    10.05FZSZ Day2模拟总结
    Tarjan求LCA
    数据结构
  • 原文地址:https://www.cnblogs.com/hznudreamer/p/13236754.html
Copyright © 2020-2023  润新知