HDU 3033 组合背包变形 I love sneakers!
I love sneakers!
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4503 Accepted Submission(s):
1845
awesome amount of scholarship. As a great zealot of sneakers, he decides to
spend all his money on them in a sneaker store.
There are
several brands of sneakers that Iserlohn wants to collect, such as Air Jordan
and Nike Pro. And each brand has released various products. For the reason that
Iserlohn is definitely a sneaker-mania, he desires to buy at least one product
for each brand.
Although the fixed price of each product has been labeled,
Iserlohn sets values for each of them based on his own tendency. With handsome
but limited money, he wants to maximize the total value of the shoes he is going
to buy. Obviously, as a collector, he won’t buy the same product twice.
Now,
Iserlohn needs you to help him find the best solution of his problem, which
means to maximize the total value of the products he can buy.
begins with three integers 1<=N<=100 representing the total number of
products, 1 <= M<= 10000 the money Iserlohn gets, and 1<=K<=10
representing the sneaker brands. The following N lines each represents a product
with three positive integers 1<=a<=k, b and c, 0<=b,c<100000,
meaning the brand’s number it belongs, the labeled price, and the value of this
product. Process to End Of File.
maximum total value of the sneakers that Iserlohn purchases. Print "Impossible"
if Iserlohn's demands can’t be satisfied.
1 4 6
2 5 7
3 4 99
1 55 77
2 44 66
分组背包问题,大意**要买鞋,有k种牌子,每种牌子至少买一双鞋子。每双鞋子有标价跟实际价值。求用m多的钱买最多价值的鞋。
其实我觉得这题的难点就在处理“至少”这点上面。
状态方程很多都能推出用 dp[k][m] 来表示 已经买了k种鞋 在有m钱状态下的 鞋的最大价值。
状态转移方程为
for( k = 1 ; k <= K ; k++)
{
for( i = 0 ; i < num[k] ; i++)
{
for( j = mm ; j >= m[k][i].m ; j--)
{
if(dp[k][j - m[k][i].m] != -1)
dp[k][j] = Max(dp[k][j] , dp[k][j - m[k][i].m] + m[k][i].v);
if(dp[k-1][j - m[k][i].m] != -1 )
dp[k][j] = Max(dp[k][j] , dp[k-1][j - m[k][i].m] + m[k][i].v);
}
}
}
如果忽略了两个红色的判断句,大家都看得出这只是单纯的01背包且 没有条件限制,加了这两句就能实现至少了。理由如下
一开始我将dp[][]数组初始化为-1表示所有的数都不合法。大于0表示合法
然后将所有的 k = 0 dp[0][]置为0,这是为了 k = 1时能合法计算。
从状态方程中看出,当上一个状态值为-1时表示他不合法。所以当前状态没有计算的必要也不合法答案。
如果计算完第k类商品的取值后,所有的dp[k][]均为-1的时候,第k类表明没有一鞋被买。故所有状态都不合法,接下来的所有值也都将不合法。
在计算第k组商品的过程中,当某个-1变成一个非负数的时候,也就表明当前的第k种已经拿了第i件物品,所以变成合法答案了。
如此推下去,最后一个值dp[k][m],就是答案了。如果依然是-1,就输出impossible把。
5 13 3
1 2 3
1 4 6
2 10 2
3 2 2
3 1 2
7
m k=0 k=1 k=2 k=3
0 0 -1 -1 -1
1 0 -1 -1 -1
2 0 3 -1 -1
3 0 3 -1 -1
4 0 6 -1 -1
5 0 6 -1 -1
6 0 9 -1 -1
7 0 9 -1 -1
8 0 9 -1 -1
9 0 9 -1 -1
10 0 9 -1 -1
11 0 9 -1 -1
12 0 9 5 -1
13 0 9 5 7
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int w;
int v;
}que[][];
int num[];
int dp[][];
int main(){
int n,m,kk;
while(scanf("%d%d%d",&n,&m,&kk)!=EOF){
memset(num,,sizeof(num));
memset(dp,-,sizeof(dp));
for(int i=;i<=n;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
que[x][num[x]].w=y;
que[x][num[x]].v=z;
num[x]++;
}
for(int i=;i<=m;i++)
dp[][i]=;
for(int i=;i<=kk;i++){
for(int k=;k<num[i];k++){
for(int j=m;j>=que[i][k].w;j--){
if(dp[i][j-que[i][k].w]!=-)
dp[i][j]=max(dp[i][j],dp[i][j-que[i][k].w]+que[i][k].v);
if(dp[i-][j-que[i][k].w]!=-)
dp[i][j]=max(dp[i][j],dp[i-][j-que[i][k].w]+que[i][k].v);
}
}
}
if(dp[kk][m]<)
printf("Impossible\n");
else
printf("%d\n",dp[kk][m]);
}
return ;
}
HDU 3033 组合背包变形 I love sneakers!的更多相关文章
- HDU 3033 分组背包变形(每种至少一个)
I love sneakers! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 1203 01背包变形题,(新思路)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1203 I NEED A OFFER! Time Limit: 2000/1000 MS (Java/ ...
- hdu 3466 01背包变形【背包dp】
http://acm.hdu.edu.cn/showproblem.php?pid=3466 有两个物品P,Q,V分别为 3 5 6, 5 10 5,如果先dp第一个再dp第二个,背包容量至少要为3+ ...
- hdu 2184 01背包变形
转自:http://blog.csdn.net/liuqiyao_01/article/details/8753686 题意:这是又是一道01背包的变体,题目要求选出一些牛,使smartness和fu ...
- hdu 4381(背包变形)
题意: 给定n个块,编号从1到n,以及m个操作,初始时n个块是白色. 操作有2种形式: 1 ai xi : 从[1,ai]选xi个块,将这些块涂白. 2 ai xi:从[ai,n]选xi个块,将这些块 ...
- HDU 3033 分组背包(至少选一个)
分组背包(至少选一个) 我真的搞不懂为什么,所以现在就只能当作是模板来用吧 如果有大牛看见 希望评论告诉我 &代码: #include <cstdio> #include < ...
- HDU 6092 01背包变形
Rikka with Subset Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- HDU 3466 01背包变形
给出物品数量N和总钱数M 对于N个物品.每一个物品有其花费p[i], 特殊值q[i],价值v[i] q[i] 表示当手中剩余的钱数大于q[i]时,才干够买这个物品 首先对N个物品进行 q-p的排序,表 ...
- HDU 3033 分组背包
给出N个物品.M金钱.W种类 给出N个物品的性质:所属种类,花费.价值 求每一种类物品至少一个的前提下,所能购买到的最大价值 dp[i][k]表示在第i种物品.总花费为k的最大价值 dp[i][k]= ...
随机推荐
- 【P1330】 封锁阳光大学
两个和谐河蟹不能在同一条边的两端.所以对于每条边.只有一个节点有和谐河蟹 所以说,我们可以将有和谐河蟹的看做一种颜色,或则是状态.没有河蟹看做另一种言颜色 这样边变成了二分图染色 所以嗯~(・∀・) ...
- es6-promise.auto.js
使用sweetalert2的IE浏览器报错,导入文件 链接:https://pan.baidu.com/s/1mOcsN_o8m-7I7Rej1NPkiw 提取码:9xsj
- 使用session处理用户搜索后数据的上一页和下一页跳转
搜索语句界面: /*单一检索:此处为一个下拉列表的检索*/ if(isset($_POST['submit']) && $_POST['submit'] == '点击搜索') { if ...
- ECMAscript6(ES6)新特性语法总结(一)
ES6/ES2015,,在ES5的基础上扩展了很多新的功能,在使用的时候要慎重,因为有一部分js代码在部分浏览器是不兼容的,但是所有写在服务器端的代码基本上都支持ES6的写法. 新特性: 一.开启严格 ...
- 折腾Vscode写C++
一直以来都是用Sublime Text3写C/C++.因为ST配置简单,轻量.闲来没事才弄一弄. 1. 新建文件夹C++Code,并且再建立一个bulid文件夹来放要写的代码. 2. 在Vscod ...
- mongodb多个查询语句
db.getCollection('costitems').find({"created":{"$gte":ISODate("2019-01-02T0 ...
- LeetCode979. 在二叉树中分配硬币
问题:979. 在二叉树中分配硬币 给定一个有 N 个结点的二叉树的根结点 root,树中的每个结点上都对应有 node.val 枚硬币,并且总共有 N 枚硬币. 在一次移动中,我们可以选择两个相邻的 ...
- 微信网页授权access_token与基础支持的access_token
问题1:网页授权access_token与分享的jssdk中的access_token一样吗? 答:不一样.网页授权access_token 是一次性的,而基础支持的access_token的是有时间 ...
- redis源代码结构解析
看了黄建宏老师的<Redis设计与实现>,对redis的部分实现有了一个简明的认识: 之前面试的时候被问到了这部分的内容,没有关注,好在还有时间,就把Redis的源码看了一遍. Redis ...
- PHP的IMAP函数
imap_8bit -转换的8位字符串的引用,打印字符串 imap_alerts -返回所有的I MAP邮件警报已经发生 imap_append -附加了一系列的信息到指定邮箱 imap_base64 ...