hdu3033 I love sneakers! 分组背包变形(详解)
这个题很怪,一开始没仔细读题,写了个简单的分组背包交上去,果不其然WA。
题目分析:
分组背包问题是这样描述的:有K组物品,每组 i 个,费用分别为Ci ,价值为Vi,每组物品是互斥的,只能取一个或者不取(最多取一个),求在一定背包容量V的情况下,能够获得的最大价值。
而这个题是,他每个牌子的鞋最少会买一双,但不会买一个牌子同款的两次。
也就是说如果将每个牌子分成一组,那么在每组里面要至少取一双,所以这更像是在每组里面进行01背包。
普通的分组背包的三层循环是:
for(int k=; k<K; k++)
for(int v=V; v>=; v--)
for(int i=; i<num[k]; i++)
if(v>a[k][i].c)
dp[v] = max(dp[v], dp[v-a[k][i].c] + a[k][i].v);
这三层循环的顺序保证了每一组最多有一个被选中。
所以如果要对每一组进行01背包要将2、3层循环换位置
但这样还不够,想想看,每一组其实是在上一组的基础上进行的01背包,这样才能得到总体的最大值。
每一次更新取得应该是:
max(dp[k][v], dp[k][v-a[k][i].c]+a[k][i].v, dp[k-1][v-a[k][i].c]+a[k][i].v)
上一组得01背包基础上,和这一组前面01背包的基础上,找到的最大值。
dp[k][v-a[k][i].c]+a[k][i].v 是这一组前面01背包状态基础上,转移到目前状态
dp[k-1][v-a[k][i].c]+a[k][i].v 是上一组01背包状态基础上,转移到目前状态
所以这就要注意,这个基础是要能够到达的,在初始化dp数组时要这样:
memset(dp, -, sizeof(dp));
memset(dp[], , sizeof(dp[]));
-1表示不可到达的状态。 这里不明白的话,应该细细体会一下,下面是修改后的三层循环:
for(int k=; k<K; k++)
for(int i=; i<num[k]; i++)
for(int v=V; v>=a[k][i].c; v--)
{
if(dp[k][v-a[k][i].c]!=-) //本组内状态是可以到达的,这是在前面01背包的基础上
dp[k][v] = max(dp[k][v], dp[k][v-a[k][i].c]+a[k][i].v);
if(dp[k-][v-a[k][i].c]!=-) //前组状态是可以到达的,这是在前组01背包的基础上
dp[k][v] = max(dp[k][v], dp[k-][v-a[k][i].c]+a[k][i].v);
}
最后输出时候如果dp[k][m] 也就是我们要求的最终答案,为-1的话,意思是这个状态是不可到达的,那我们就要输出“Impossible”;
下面是AC代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> int max(int a, int b)
{
return a>b? a:b;
} struct dat
{
int c;
int v;
} data[][]; int main()
{
int n, m, k;
int a,b,c;
int dp[][];
int count[];
while(scanf("%d%d%d", &n, &m, &k)!=-)
{
memset(dp, -, sizeof(dp));
memset(dp[], , sizeof(dp[]));
memset(count, , sizeof(count)); for(int i=; i<n; i++)
{
scanf("%d%d%d", &a, &b, &c);
data[a][count[a]].c = b;
data[a][count[a]++].v = c;
} for(int i=; i<=k; i++)
{
for(int j=; j<count[i]; j++)
for(int v=m; v>=data[i][j].c; v--)
{
if(dp[i][v-data[i][j].c]!=-)
dp[i][v] = max(dp[i][v], dp[i][v-data[i][j].c]+data[i][j].v);
if(dp[i-][v-data[i][j].c]!=-)
dp[i][v] = max(dp[i][v], dp[i-][v-data[i][j].c]+data[i][j].v);
}
}
if(dp[k][m]==-)
printf("Impossible\n");
else
printf("%d\n", dp[k][m]);
}
return ;
}
hdu3033 I love sneakers! 分组背包变形(详解)的更多相关文章
- hdu3033 I love sneakers! 分组背包变形
分组背包要求每一组里面只能选一个,这个题目要求每一组里面至少选一个物品. dp[i, j] 表示前 i 组里面在每组至少放进一个物品的情况下,当花费 j 的时候,所得到的的最大价值.这个状态可以由三个 ...
- HDU3033 I love sneakers!———分组背包
这题的动态转移方程真是妙啊,完美的解决了每一种衣服必须买一件的情况. if(a[x][i-c[x][j].x]!=-1) a[x][i]=max(a[x][i],a[x][i-c[x][j].x]+c ...
- python 之re模块(正则表达式) 分组、断言详解
正则表达式分组.断言详解 提示:阅读本文需要有一定的正则表达式基础. 正则表达式中的断言,作为高级应用出现,倒不是因为它有多难,而是概念比较抽象,不容易理解而已,今天就让小菜通俗的讲解一下. 如果 ...
- I love sneakers!(分组背包HDU3033)
I love sneakers! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 3033 分组背包变形(每种至少一个)
I love sneakers! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3033 I love sneakers! 分组背包
I love sneakers! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3033 I love sneakers!(分组背包+每组至少选一个)
I love sneakers! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU3033I love sneakers!(分组背包)
http://acm.hdu.edu.cn/showproblem.php?pid=3033 本题的意思就是说现在有n种牌子的鞋子,每种品牌有一些不同的鞋,每双鞋子都有一个特定的权值,现在要求每种品牌 ...
- HD3033I love sneakers!(分组背包+不懂)
I love sneakers! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- P1345 [USACO5.4]奶牛的电信(点拆边 + 网络最小割)
题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,-,a©,且a1与a2相连,a2 ...
- P3381 【模板】最小费用最大流(MCMF)
P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入格式 第一行包含四个正整数N ...
- Java 程序该怎么优化?(技巧篇)
搬砖者:为什么程序总是那么慢?它现在到底在干什么?时间都花到哪里去了? 面试官:简单谈谈 Java 程序性能优化? 1. 字符串处理优化,乃优化之源. 研发过程中,String 的 API 用的应该是 ...
- wifi无线桥接
考虑到不同路由器配置上或许有细微差别,我此处路由器是水星(牌子)路由器. 首先需要2台路由器,一台已经能够上网,作为主路由器:另一台啥都没有配置,将来用作副路由器,与主路由器桥接. 步骤: 获取主路由 ...
- 获取data 数据
export function getData(el, name, val) { const prefix = 'data-' if (val) { return el.setAttribute(pr ...
- 携程首页--使用flex布局实现
携程首页 flex解决了float和postion的遗留问题,对移动端比较友好. 需要水平排列的元素就为其父元素设置display:flex,并为子元素添加flex的值(比例) 布局时可以先从大的页面 ...
- PTA数据结构与算法题目集(中文) 7-40奥运排行榜 (25 分)
PTA数据结构与算法题目集(中文) 7-40奥运排行榜 (25 分) 7-40 奥运排行榜 (25 分) 每年奥运会各大媒体都会公布一个排行榜,但是细心的读者发现,不同国家的排行榜略有不同.比如 ...
- GoLang——Hello World,打开新世界的大门
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Go语言系列的第一篇文章,我们来聊聊这门新的语言和它的基础语法. 浅谈Golang 作为程序员而言,往往对于学习新的语言都是有抗拒的. ...
- 关于Cookie的相关知识点以及使用方法
首先介绍cookie的一些方法 response.addCookie(Cookie cookie)是将一个cookie对象传入客户端. Cookie cookie=new Cookie(String ...
- MTK Android ListPreference的用法
首先,我们明确,preference是和数据存储相关的. 其次,它能帮助我们方便的进行数据存储!为什么这个地方一定要强调下方便的这个词呢?原因是,我们可以根本就不使用,我们有另外的N种办法可以实现同样 ...