华师一附中OI组

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 877|回复: 2
打印 上一主题 下一主题

P1757 通天之分组背包

[复制链接]

738

主题

1485

帖子

5422

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5422
跳转到指定楼层
楼主
发表于 2018-6-3 21:51:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
https://www.luogu.org/problemnew/show/P1757

题目背景
直达通天路·小A历险记第二篇

题目描述
自01背包问世之后,小A对此深感兴趣。一天,小A去远游,却发现他的背包不同于01背包,他的物品大致可分为k组,每组中的物品相互冲突,现在,他想知道最大的利用价值是多少。

输入输出格式
输入格式:
两个数m,n,表示一共有n件物品,总重量为m

接下来n行,每行3个数ai,bi,ci,表示物品的重量,利用价值,所属组数

输出格式:
一个数,最大的利用价值

输入输出样例
输入样例#1:
45 3
10 10 1
10 5 1
50 400 2
输出样例#1:
10
说明
1<=m<=1000 1<=n<=1000 组数t<=100
回复

使用道具 举报

7

主题

27

帖子

91

积分

注册会员

Rank: 2

积分
91
沙发
发表于 2018-6-5 18:01:31 | 只看该作者
  1. #include <cstdio>
  2. #include <algorithm>
  3. typedef long long LL;
  4. using namespace std;

  5. const int N = 1010;
  6. const LL INF = 1ll << 62;

  7. struct A {
  8.     LL cost, val, group;
  9.     bool operator < (const A &x) {
  10.         return group < x.group;
  11.     }
  12. }a[N];

  13. struct Group {
  14.     LL s, t, small;
  15. }g[N];

  16. LL f[N];

  17. int main() {
  18.     LL V, n;
  19.     scanf("%lld%lld", &V, &n);
  20.     for(int i = 1; i <= n; i++) {
  21.         scanf("%lld%lld%lld", &a[i].cost, &a[i].val, &a[i].group);
  22.     }
  23.     sort(a + 1, a + n + 1);
  24.     for(int i = 1; i <= n; i++) {
  25.         if(a[i].group != a[i - 1].group) {
  26.             g[a[i].group].s = i;
  27.         }
  28.         g[a[i].group].t = i;
  29.     }
  30.     for(int i = 1; i <= a[n].group; i++) {
  31.         g[i].small = INF;
  32.         for(int j = g[i].s; j <= g[i].t; j++) {
  33.             g[i].small = min(g[i].small, a[j].cost);
  34.         }
  35.     }
  36.    
  37.     for(int k = 1; k <= a[n].group; k++) { /// k-th group
  38.         for(int i = V; i >= g[k].small; i--) { /// i V
  39.             for(int j = g[k].s; j <= g[k].t; j++) { /// j which
  40.                 if(i >= a[j].cost) {
  41.                     f[i] = max(f[i], f[i - a[j].cost] + a[j].val);
  42.                 }
  43.             }
  44.         }
  45.     }
  46.     LL ans = 0;
  47.     for(int i = 1; i <= V; i++) {
  48.         ans = max(ans, f[i]);
  49.     }
  50.     printf("%lld", ans);
  51.     return 0;
  52. }
复制代码
回复 支持 反对

使用道具 举报

2

主题

105

帖子

306

积分

中级会员

Rank: 3Rank: 3

积分
306
板凳
发表于 2018-7-30 00:08:05 | 只看该作者
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <cmath>
  4. #include <cstring>
  5. #include <map>
  6. #include <string>
  7. #include <vector>
  8. #include <queue>
  9. #include <stack>
  10. #include <cstdio>
  11. #include <cstdlib>
  12. using namespace std;
  13. vector <int> v[1100],w[1100];
  14. int f[1100],m,n,T=0;
  15. int main()
  16. {
  17.     scanf("%d%d",&m,&n);
  18.     for(int i=1;i<=n;i++)
  19.     {
  20.         int v1,w1,a1;
  21.         scanf("%d%d%d",&w1,&v1,&a1);
  22.         v[a1].push_back(v1);
  23.         w[a1].push_back(w1);
  24.         T=max(T,a1);
  25.     }
  26.     for(int i=1;i<=T;i++)
  27.             for(int j=m;j>=0;j--)
  28.                     for(int k=0;k<v[i].size();k++)
  29.                             if(j>=w[i][k])
  30.                                     f[j]=max(f[j],f[j-w[i][k]]+v[i][k]);
  31.     printf("%d",f[m]);
  32.     return 0;
  33. }
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|服务支持:DZ动力|华师一附中OI组  

GMT+8, 2024-12-26 02:02 , Processed in 0.288303 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表