HDU 3033 I love sneakers! 我爱运动鞋 (分组背包+01背包,变形)
题意:
有n<=100双鞋子,分别属于一个牌子,共k<=10个牌子。现有m<=10000钱,问每个牌子至少挑1双,能获得的最大价值是多少?
思路:
分组背包的变形,变成了相反的,每组物品至少挑1件(分组背包问题是至多挑1件)。
由于每个牌子至少买1双,那么可以先装一件最便宜的进去,如果有好的再更新(注意每次的容量下限)。而且同一双鞋子不能多次购买,这里要用01背包。对于当前容量cap,可能只装了某一牌子的一双鞋子(不一定最便宜),也可能装了多双,也可能只装了那双硬塞进去的最便宜的。
注意点:有的店可是不一定有鞋子的;可能某个牌子连一双都买不起;可能买不全所有牌子。
重写了次:
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <deque>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define back que[rear-1]
#define INF 0x3f3f3f3f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI = acos(-1.0);
const int N=;
int dp[][N];
struct node
{
int p,v;
}r;
vector<node> vect[N];
inline int cmp(node a,node b){return a.p<b.p;}
bool cal(int n,int m,int k)
{
for(int i=; i<=n; i++) //排序方便处理
sort(vect[i].begin(),vect[i].end(),cmp);
int sum=; //最便宜的鞋子价钱之和
for(int i=; i<=k; i++) //枚举组
{
if(vect[i].empty()) return false; //无鞋 node a=vect[i][];
for(int j=m; j-a.p>=sum; j--) //先装进去一个最便宜的
dp[i][j]=dp[i-][j-a.p]+a.v; for(int t=; t<vect[i].size(); t++) //考虑此组其他鞋
{
a=vect[i][t];
for(int j=m; j-a.p>=sum; j--)
{
dp[i][j]=max(dp[i][j], dp[i-][j-a.p]+a.v ); //注意点
dp[i][j]=max(dp[i][j], dp[i][j-a.p]+a.v );
}
}
sum+=vect[i][].p;
if(sum>m) return false; //买不起
}
return true;
} int main()
{
//freopen("input.txt", "r", stdin);
int w, n, m, k;
while(cin>>n>>m>>k) //n双鞋子,m钱,k个牌子
{
memset(dp,,sizeof(dp));
for(int i=; i<=k; i++) vect[i].clear();
for(int i=; i<=n; i++)
{
scanf("%d%d%d", &w, &r.p, &r.v);
vect[w].push_back(r); //分组保存
}
if(cal(n,m,k)) printf("%d\n",dp[k][m]);
else printf("Impossible\n");
}
return ;
}
AC代码
#include <bits/stdc++.h>
using namespace std;
int n, m, k, w, dp[][];
struct node
{
int p,v;
}r;
vector< vector<node> > vect;
inline int cmp(node a,node b){return a.p< b.p? : ;}
int cal()
{
memset(dp,,sizeof(dp));
int up=;
for(int i=; i<=k; i++) //每组
{
r=vect[i][];
for(int j=m; j>=up+r.p; j--) //先装进去每组中最便宜的一个,有更好的再更新
dp[i][j]=dp[i-][j-r.p]+r.v; for(int t=; t<vect[i].size(); t++)//同组每种鞋
{
r=vect[i][t];
for(int j=m; j>=up+r.p; j--) //每种容量。注意下限是前面所有店的最便宜鞋价的总和。最差也能买上前面所有店的最便宜的鞋子,其他都是无效的状态。
{
dp[i][j]=max(dp[i][j], dp[i-][j-r.p]+r.v ); //单独放。
dp[i][j]=max(dp[i][j], dp[i][j-r.p] +r.v ); //配合同组放。
}
}
up+=vect[i][].p; //更新下限
}
if(dp[k][m]>) return ;
else return ;
}
void init()
{
vect.clear();
vector<node> tmp;
for(int i=; i<=k; i++) vect.push_back(tmp);
} int main()
{
freopen("input.txt", "r", stdin);
while(cin>>n>>m>>k)
{
init();
for(int i=; i<n; i++)
{
scanf("%d%d%d", &w, &r.p, &r.v);
vect[w].push_back(r);//分组保存
}
int big=;
for(int i=; i<=k; i++)
{
sort(vect[i].begin(), vect[i].end(), cmp); //排个序,最低价的排在前面
if(!vect[i].empty()) big+=vect[i][].p; //坑在这,有的店完全没有鞋子!
else big=0x7fffffff;//既然没有鞋子,置为无穷大,表示买不起。
}
if(big>m){printf("Impossible\n");continue;} //每家店最便宜的鞋子都买不起
if(cal()) printf("%d\n",dp[k][m]);
else printf("Impossible\n");
}
return ;
}
AC代码
HDU 3033 I love sneakers! 我爱运动鞋 (分组背包+01背包,变形)的更多相关文章
- 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! (动态规划分组背包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3033 题意:给你K种品牌,每种品牌有不同种鞋,现在每种品牌至少挑一款鞋,问获得的最大价值,如果不能每种 ...
- 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) ...
- hdu 2126 Buy the souvenirs 【输出方案数】【01背包】(经典)
题目链接:https://vjudge.net/contest/103424#problem/K 转载于:https://blog.csdn.net/acm_davidcn/article/detai ...
- HDU 1011 Starship Troopers【树形DP/有依赖的01背包】
You, the leader of Starship Troopers, are sent to destroy a base of the bugs. The base is built unde ...
- HDU - 5887 2016青岛网络赛 Herbs Gathering(形似01背包的搜索)
Herbs Gathering 10.76% 1000ms 32768K Collecting one's own plants for use as herbal medicines is pe ...
- HDU 3033 组合背包变形 I love sneakers!
I love sneakers! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- hdu 3033(好题,分组背包)
I love sneakers! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- Fitnesse中TemplateLibrary的使用方法
1.新建一个SuitePage,命名为TemplateLibrary 2.然后如下图,添加作为template的TestPage,如下面的Get 3.在Get page中添加template内容,如下 ...
- Linux环境下Nginx及负载均衡
Nginx 简介 Nginx 是一个高性能的 HTTP 和反向代理 Web 服务器,同时也提供了 IMAP/POP3/SMTP 服务.前向代理作为客户端的代理,服务端只知道代理的 IP 地址而不知道客 ...
- html5代码如何转成小程序代码
插件源码 链接:https://pan.baidu.com/s/1pGY8ZsdESaQGEzoEgpb_Rw 提取码:s1ix 放到与pages文件夹同级目录下 js中调用 //引入 var wx ...
- 利用YYLabel 进行图文混排+高度计算
利用YYLabel 进行图文混排+高度计算 1.项目需求: 用一个控件显示图片和文字,并且依据图片和文字动态计算控件的高度. 2.方案: 利用YYLabel控件和属性字符串处理. 注:(在使用YYLa ...
- WINDOWS编程基础-最简单的windows程序
流程 1 建立并注册windows类 2 使用windows类创建窗口 3 实现事件处理,主循环 PeekMessage与GetMessage的对比 相同点: PeekMessage函数与GetMes ...
- [Xcode 实际操作]八、网络与多线程-(18)PerformSelector消息处理方法:由运行时系统,负责去调用对象的指定方法
目录:[Swift]Xcode实际操作 本文将演示PerformSelector消息处理方法. 在项目文件夹上点击鼠标右键弹出文件菜单. [New File]->[Swift File]-> ...
- apringboot aop权限控制
+ 定义切面: ···@Aspect @Component public class LoginInterceptor { @Around("@annotation(lock)") ...
- 花花的森林(倍增,LCA
花花的森林,嗯,这是一篇正经的题解. 模拟考的时候没有看出来要怎么求啊,暴力地树形DP.换根.合并.求直径.居然也险险地拿到了80分,不过我们要正经地想正解. 容易想到我们可以让时光倒流,让空间扭转, ...
- extern用法详解(转)
1 基本解释 extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义. 另外,extern也可用来进行链接指定. 2 问题:ext ...
- 几例实用的Shell脚本
日常工作中,经常编写一些shell命令或脚本以完成重复性操作,本文分享了最近用到的几例shell实用脚本. 1 特殊文件名的远程拷贝 服务器之间拷贝文件经常使用scp命令,其命令格式: (1)scp ...