这个题很怪,一开始没仔细读题,写了个简单的分组背包交上去,果不其然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! 分组背包变形(详解)的更多相关文章

  1. hdu3033 I love sneakers! 分组背包变形

    分组背包要求每一组里面只能选一个,这个题目要求每一组里面至少选一个物品. dp[i, j] 表示前 i 组里面在每组至少放进一个物品的情况下,当花费 j 的时候,所得到的的最大价值.这个状态可以由三个 ...

  2. 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 ...

  3. python 之re模块(正则表达式) 分组、断言详解

    正则表达式分组.断言详解   提示:阅读本文需要有一定的正则表达式基础. 正则表达式中的断言,作为高级应用出现,倒不是因为它有多难,而是概念比较抽象,不容易理解而已,今天就让小菜通俗的讲解一下. 如果 ...

  4. I love sneakers!(分组背包HDU3033)

    I love sneakers! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  5. HDU 3033 分组背包变形(每种至少一个)

    I love sneakers! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. hdu 3033 I love sneakers! 分组背包

    I love sneakers! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. hdu 3033 I love sneakers!(分组背包+每组至少选一个)

    I love sneakers! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  8. HDU3033I love sneakers!(分组背包)

    http://acm.hdu.edu.cn/showproblem.php?pid=3033 本题的意思就是说现在有n种牌子的鞋子,每种品牌有一些不同的鞋,每双鞋子都有一个特定的权值,现在要求每种品牌 ...

  9. HD3033I love sneakers!(分组背包+不懂)

    I love sneakers! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

随机推荐

  1. 一夜搞懂 | Java 内存模型与线程

    前言 本文已经收录到我的 Github 个人博客,欢迎大佬们光临寒舍: 我的 GIthub 博客 学习导图 一.为什么要学习内存模型与线程? 并发处理的广泛应用是 Amdah1 定律代替摩尔定律成为计 ...

  2. 1127: 【入门】A类多?B类多?

    1127: [入门]A类多?B类多? 时间限制: 1 Sec 内存限制: 16 MB 提交: 3537 解决: 2406 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 一个自然数转换 ...

  3. P1004 方格取数(四维dp)

    P1004 方格取数 思路如下 这题是看洛谷大佬的思路才写出来的,所以我会把大佬的思路展示如下: 1⃣️:我们可以找到一个叫思维dp的东西,dp[i][j][k][l],其中前两维表示一个人从原点出发 ...

  4. Vue点击当前元素添加class 去掉兄弟的class

    <div id="app"> <ul> <li v-for="(todo, index) in todos" v-on:click ...

  5. Redis 笔记(三)—— LIST 常用命令

    常用命令 命令 用例和描述 RPUSH RPUSH key value [value ...] —— 将一个或多个值推入列表的右端 LPUSH LPUSH key value [value ...] ...

  6. QT-day1 创建项目

  7. Nginx知多少系列之(六)Linux下.NET Core项目负载均衡

    目录 1.前言 2.安装 3.配置文件详解 4.工作原理 5.Linux下托管.NET Core项目 6.Linux下.NET Core项目负载均衡 7.负载均衡策略详解 8.Linux下.NET C ...

  8. Atlas运行时资源不足报错 -bash: fork: retry: 资源暂时不可用 Out of system resources

    目的:运行Atlas并使用Azkaban执行操作任务 环境:Centos 6 内存大小:12G 启动下面的任务后还剩内存将近5G 问题: 当mysql_to_hdfs_db和其他job同时运行时集群很 ...

  9. vue 中 history 模式的配置和打包

    在使用 vue 进行项目开发中,默认的路由形式是 hash,表现形式就是 url 中始终带有 # 号,在后台管理类的项目中并不影响使用,但是在特殊场景,比如微信分享的H5链接中,微信会自动拼接参数,由 ...

  10. AJ学IOS(06)UI之iOS热门游戏_超级猜图

    AJ分享,必须精品 先看效果图 思路 需求分析 1,搭建界面 1>上半部分,固定的,用Storyboard直接连线(OK) 2>下半部分,根据题目的变化,不断变化和调整,用代码方式实现比较 ...