题目链接:https://vjudge.net/problem/POJ-1170

题意:输入n,表示有那种物品,接下来n行,每行a,b,c三个变量,a表示物品种类,b是物品数量,c代表物品的单价。接下来一个数字m,表示有m个套餐,接下来m行,每行一个数字k,表示有k对数字,后面接k对数字,分别是物品种类和物品数量,最后一个value代表这个套餐的价格(套餐价格一定比单独买这些东西的价格低)。现在要我们求出买上面所有东西所需要的最低价格。

分析数据会发现物品种类会超过5,每种物品数量不会超过5,所以可以用状态压缩,虽然我第一发是用完全背包加六个循环...

思路就是这样,具体看代码:

状压dp:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<set>
#include<cstdio>
#include<string>
#include<deque>
using namespace std;
typedef long long LL;
#define eps 1e-8
#define INF 0x3f3f3f3f
#define maxn 50005
/*struct point{
int u,w; };
bool operator <(const point &s1,const point &s2)
{
if(s1.w!=s2.w)
return s1.w>s2.w;
else
return s1.u>s2.u;
}*/
map<int,int>mp;
int n,m,k,t,MAX;
int num[],value[],vis[maxn];//vis标记i这个数字是不是超出了物品最大数量
int bit[];
int dp[maxn];
struct node{
int state,value;//记录套餐的状态压缩的值和套餐价格
}item[];
int check(int a)//检查a这个数字是不是每一种物品数量都不超出数量限制
{
for(int i=;i<&&a;i++){
if(a%>num[i])
return false;
a/=;
}
return true;
}
int cal(int a)//计算状态压缩值a在不考虑套餐情况下需要的花费
{
int ans=;
for(int i=;i<&&a;i++){
ans+=(a%)*value[i];
a/=;
}
return ans;
}
void init()//把每一个状态在不考虑套餐是需要的花费1计算出来
{
memset(dp,,sizeof(dp));
for(int i=;i<=MAX;i++){
if(check(i))
{
vis[i]=;//表示i是可行的
dp[i]=cal(i);
}
}
}
int main()
{
bit[]=;
for(int i=;i<=;i++){
bit[i]=bit[i-]*;
}
while(scanf("%d",&n)!=EOF){
memset(num,,sizeof(num));
memset(vis,,sizeof(vis));
MAX=;
int id=,a,b,c;
mp.clear();
for(int i=;i<=n;i++){
scanf("%d%d%d",&a,&b,&c);
if(mp[a]==)
mp[a]=id++;//给物品编号
num[mp[a]]=b;
value[mp[a]]=c;
MAX+=b*bit[mp[a]];
}
scanf("%d",&m);
for(int i=;i<=m;i++){
scanf("%d",&k);
int state=;
for(int j=;j<=k;j++){
scanf("%d%d",&a,&b);
state+=b*bit[mp[a]];
}
item[i].state=state;
scanf("%d",&item[i].value);
}
init();
for(int i=;i<=m;i++){
for(int j=item[i].state;j<=MAX;j++){
if(vis[j]&&vis[j-item[i].state])//j和j-item[i].state都不超出限制
dp[j]=min(dp[j],dp[j-item[i].state]+item[i].value);
}
}
printf("%d\n",dp[MAX]);
}
return ;
}

六个循环的代码就不写了,傻乎乎啊。

poj 1170状压dp的更多相关文章

  1. POJ 3254 (状压DP) Corn Fields

    基础的状压DP,因为是将状态压缩到一个整数中,所以会涉及到很多比较巧妙的位运算. 我们可以先把输入中每行的01压缩成一个整数. 判断一个状态是否有相邻1: 如果 x & (x << ...

  2. POJ 3254 状压DP

    题目大意: 一个农民有一片n行m列 的农场   n和m 范围[1,12]  对于每一块土地 ,1代表可以种地,0代表不能种. 因为农夫要种草喂牛,牛吃草不能挨着,所以农夫种菜的每一块都不能有公共边. ...

  3. POJ 2411 状压DP经典

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 16771   Accepted: 968 ...

  4. poj 3254 状压dp入门题

    1.poj 3254  Corn Fields    状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...

  5. poj 1185(状压dp)

    题目链接:http://poj.org/problem?id=1185 思路:状态压缩经典题目,dp[i][j][k]表示第i行状态为j,(i-1)行状态为k时最多可以放置的士兵个数,于是我们可以得到 ...

  6. poj 2923 状压dp+01背包

    好牛b的思路 题意:一系列物品,用二辆车运送,求运送完所需的最小次数,两辆车必须一起走 解法为状态压缩DP+背包,本题的解题思路是先枚举选择若干个时的状态,总状态量为1<<n,判断这些状态 ...

  7. Islands and Bridges(POJ 2288状压dp)

    题意:给你一个图和每个点的价值,边权值为连接两点权值的积,走哈密顿通路,若到达的点和上上个点相连则价值加三点乘积,求哈密顿通路的最大价值,和最大价值哈密顿通路的条数. 分析:开始看这个题很吓人,但想想 ...

  8. Hie with the Pie(POJ 3311状压dp)

    题意:披萨店给n个地方送披萨,已知各地方(包括披萨店)之间花费的时间,求送完所有地方并回到店花费的最小时间 分析:状态好确定dp[i][j],i中1表示地方已送过,否则为0,j为当前状态最后一个送过的 ...

  9. 炮兵阵地(POJ 1185状压dp)

    题意:n*m地图'H'能放'p'不能放,布兵的方格上下左右不能布兵,给你地图求最大布兵数 分析:关系到前两行,所以dp[i][j][k]第i行状态为j,i-1行状态为k时的最大布兵数, 先求出所有可行 ...

随机推荐

  1. leetcode989

    class Solution: def addToArrayForm(self, A, K): i = len(A) - 1 while i >= 0 and K > 0: A[i] += ...

  2. 用JS 和 jQery获取屏幕的高度和宽度

    用的时候,网上找了下,放在一起,方便以后查阅 document.body.clientWidth document.body.offsetWidth(包括线宽)//网页可见区域宽 document.b ...

  3. springboot 端口号

    1. 读取端口号 2.多端口运行 2.

  4. golang判断文件/文件夹是否存在

    使用os包,os.stat返回err==nil,说明存在: os.IsNotExist(err)为true,说明不存在:否则不确定是否存在 func DelJar(fileName string) e ...

  5. jquery 基础-记住

    jquery最为一个库,简便. 难点在于选择器,筛选器的使用. 属性一般都是,jquery对象.函数(),括号内部添属性. s= '<tr> <td class="fix& ...

  6. python multithread task_done

    queue.task_done()用在queue消费者中,在queue.get()调用之后调用queue.task_done()用于通知队列已经完成了工作,使queue.join()知道任务已经完成. ...

  7. js 迭代器 解说

    这里要说的是迭代器,是一种思路而已,代码相对来不是最关键的,个人认为,最关键的部分是实现的思路 要求: 在一个网页中,将所有的 p 元素的内容进行替换,但是在特定的位置的 p 元素是要有差异的进行替换 ...

  8. harbor仓库镜像的删除

    harbor仓库镜像的删除 刚开始自己摸索了下,直接webui界面删除后,发现仓库空间未释放 上传之前仓库空间占用为 上传之后仓库空间占用为 在webui界面上删除镜像后 查看大小 依旧为286m,到 ...

  9. avalon2学习教程04显示隐藏处理

    今天的主角是ms-visible,它的效果类拟于jQuery的toggle,如果它后面跟着的表达式为真值时则显示它所在的元素,为假值时则隐藏.不过显示不是 display:none这么简单,众所周知, ...

  10. webpack打包avalon+mmRouter

    这是上一篇<webpack打包avalon+oniui+jquery>的姐妹篇,avalon 的高级应用篇.大家要知道,现在最流行的网页架构就是SPA,SPA能提高用户体验.用户许多数据都 ...