题意:有n双鞋子,m块钱,k个品牌,(一个品牌可以有多种价值不同的鞋子),接下来n种不同的鞋子,a为所属品牌,b为要花费的钱,c为所能得到的价值。每种价值的鞋子只会买一双,有个人有个伟大的梦想,每个品牌的鞋子至少买一双,问他这个梦想可以实现不?不可以实现输出Impossible,可以实现输出最大价值......

思路:很容易看出来这是个分组背包题,当然这个分组背包有些不同于每组最多取一个的分组背包......但我是觉得,分组背包就这么几种问法吧

1、最常见的、最水的,每组最多取1个.........(一般是隐性的,需要自己分析)

2、每组至少取1个........(就是本题)

3、随意选,可以选,可以不选,可以只选1个,也可以选多个......(暂时还未学,马上会学).....

对于第一种,模板题,只要你可以分析出来,那么可以水过.....

对于第二种,我想说也是模板题,当然是以本题为基础的模板.........

好吧,这道题目,首先,每组至少取一个,就是说必须要取一个,那么数组dp[i][j],代表的含义就是 前i组容量为j的情况下所得到的最大价值为dpi][j];

同样的,我们首先思考它的状态,每组必须要取一个,那么第i组存在的情况下,第i-1组也必须存在,也是回到了前面所做背包所说的那种“一定”、“必须”的状态,那么同样的在动态转移的时候,要判断它的前一个状态合不合法,我个人比较喜欢用0来判断不合法,>0判断合法.......初始化dp[0][0]=1,最后得到的结果减去1......我想说的是,最后的结果不一定会集中在dp[k][m]上,因为这个状态它不一定存在,也就是说,这个状态不一定合法,当然,也没有关系,我们考虑第k组一定要存在,那么扫描下dp[k][i],取最大值就好.....

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int dp[15][10005],s[105][2],num[15][105];
queue<int>Q[105];
int main()
{
int n,m,k;
while(scanf("%d %d %d",&n,&m,&k)>0)
{ for(int i=0;i<105;i++)
while(!Q[i].empty())
Q[i].pop();
for(int i=1;i<=n;i++)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
Q[a].push(i);
s[i][0]=b;
s[i][1]=c;
} for(int i=1;i<=k;i++)
{
int j=1;
while(!Q[i].empty())
{
num[i][j++]=Q[i].front();
//printf("i==%d %d\n",i,Q[i].front());
Q[i].pop();
}
num[i][0]=j;
} //前面都是将数据处理好
memset(dp,0,sizeof(dp)); //初始化dp
dp[0][0]=1;
int flag=1;
for(int i=1;i<=k;i++) //这是分组
{
if(num[i][0]==1) //要是有一组没有数据,那么说明,它不可能满足每组必须取一个这条件.......
{
flag=0;
break;
}
for(int f=1;f<num[i][0];f++) //不同于最多取一个的分组背包,这里是先放每组有的物品,后放容积.......
{
int xx=num[i][f];;
for(int j=m;j>=0;j--) //至于为什么这么放?我是认为,它是一种模板.......
{
if(j-s[xx][0]>=0&&dp[i][j-s[xx][0]]&&dp[i][j-s[xx][0]]+s[xx][1]>dp[i][j]) //这个判断必须放到第一,以免重复
dp[i][j]=dp[i][j-s[xx][0]]+s[xx][1]; if(j-s[xx][0]>=0&&dp[i-1][j-s[xx][0]]&&dp[i-1][j-s[xx][0]]+s[xx][1]>dp[i][j])//这个必须放在上一个判断下面.....
dp[i][j]=dp[i-1][j-s[xx][0]]+s[xx][1]; }
}
}
int maxx=0;
for(int i=0;i<=m;i++)
if(maxx<dp[k][i])
maxx=dp[k][i];
if(maxx==0||flag==0)
printf("Impossible\n");
else
printf("%d\n",maxx-1);//最大值记得减去1
}
return 0;
}

dp之分组背包hdu3033 最少取1次的解法(推荐)的更多相关文章

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

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

  2. dp之分组背包hdu3535(推荐)

    题意:有0,1,2三种任务,0任务中的任务至少得完成一件,1中的任务最多完成1件,2中的任务随便做.每一个任务最多只能做一次 .n代表有n组任务,t代表有t分钟,m代表这组任务有m个子任务,s代表这m ...

  3. dp之分组背包hdu1712

    题意:有n门课程,和m天时间,完成a[i][j]得到的价值为第i行j列的数字,求最大价值...... 思路:分组背包,就是第n门课程,可以做一天,可以做两天,但它们相斥,你做了一天,就不能再做一天.. ...

  4. 树形DP+(分组背包||二叉树,一般树,森林之间的转换)codevs 1378 选课

    codevs 1378 选课 时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond  题目描述 Description 学校实行学分制.每门的必修课都有固定的学分 ...

  5. UVA Live Archive 4015 Cave (树形dp,分组背包)

    和Heroes Of Might And Magic 相似,题目的询问是dp的一个副产物. 距离是不好表示成状态的,但是可以换一个角度想,如果知道了从一个点向子树走k个结点的最短距离, 那么就可以回答 ...

  6. Codevs1378选课[树形DP|两种做法(多叉转二叉|树形DP+分组背包)---(▼皿▼#)----^___^]

    题目描述 Description 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修 ...

  7. hdoj1561 The more, The Better (树形dp,分组背包)

    题目链接:https://vjudge.net/problem/HDU-1561 题意:给一个森林,每个结点有个权值,求选m个结点的最大权值和,并且选子结点前必须先选父结点. 思路: 把每颗树的树根连 ...

  8. poj1947(树上分组背包)

    题目链接:https://vjudge.net/problem/POJ-1947 题意:给定一棵树,求得到一个结点数为p最少删多少条边. 思路: 明显的树形dp,分组背包.用dp[u][j]表示在结点 ...

  9. 【hdu3033】分组背包(每组最少选一个)

    [题意] 有S款运动鞋,一个n件,总钱数为m,求不超过总钱数且每款鞋子至少买一双的情况下,使价值最大.如果有一款买不到,就输出“Impossible". 1<=N<=100  1 ...

随机推荐

  1. 元程序 /如何取test.py中name的值

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #Python学习手册 633 #模块是对象:元程序 #因为模块通过内置属性显示了他们的大多数特性,因此很容易 ...

  2. 类的专有方法(__del__)

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #http://www.bubuko.com/infodetail-313791.html #类的专有方法(_ ...

  3. Centos调出图形化的网络管理

    在Linux中设置网路,图形化很方便.在命令行下/etc/sysconfig/network-scripts/ifcfg-eth0 00.命令行下修正网路 [root@dzswj-test ~]#ca ...

  4. eclipse新建maven工程的各种坑

    尽量按照最后强烈推荐的那篇创建maven工程.  1.jsp文件头报错 2.xml配置文件头红叉 3.Archive for required library...blabla 4.pom依赖出错 5 ...

  5. window.postMessage实现网页间通信

    window.postMessage() 方法可以安全地实现跨域通信.通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以 ...

  6. Launchy – 快速调出你的程序

    http://www.appinn.com/launchy/这个可是今天绝对的发现,超级好玩好用的程序,Launchy 可以使你快速的调用你电脑中的程序快捷方式,而且很智能,使用起来很智能,安装后用A ...

  7. Android——点击对话框上按钮不关闭对话框

    有时候我没可能需要在点击按钮进行一些检测,但是并不想关闭次对话框(系统默认点击任何一个按钮则关闭对话框),处理方法如下:在点击事件下添加如下代码: try { Field field = dialog ...

  8. 【转】对 Go 语言的综合评价

    以前写过一些对 Go 语言的负面评价.现在看来,虽然那些评价大部分属实,然而却由于言辞激烈,没有点明具体问题,难以让某些人信服.在经过几个月实际使用 Go 来构造网站之后,我觉得现在是时候对它作一些更 ...

  9. List 集合remove问题

    java的list集合中.使用remove删除元素: 方法一: static List<Integer> list3 = new ArrayList<Integer>(); s ...

  10. SqlMapConfig.xml中的setting属性 Ibatis mybatis

    <settingscacheModelsEnabled="true"lazyLoadingEnabled="false"enhancementEnable ...