POJ 1170 暴搜+dp剪枝优先队列+状压
来源:互联网 发布:如何利用网络招聘 编辑:程序博客网 时间:2024/04/25 06:56
Description
In a shop each kind of product has a price. For example, the price of a flower is 2 ICU (Informatics Currency Units) and the price of a vase is 5 ICU. In order to attract more customers, the shop introduces some special offers.
A special offer consists of one or more product items for a reduced price. Examples: three flowers for 5 ICU instead of 6, or two vases together with one flower for 10 ICU instead of 12.
Write a program that calculates the price a customer has to pay for certain items, making optimal use of the special offers. That is, the price should be as low as possible. You are not allowed to add items, even if that would lower the price.
For the prices and offers given above, the (lowest) price for three flowers and two vases is 14 ICU: two vases and one flower for the reduced price of 10 ICU and two flowers for the regular price of 4 ICU.
Input
Output
Sample Input
27 3 28 2 521 7 3 52 7 1 8 2 10
Sample Output
14
哈哈哈哈哈哈哈哈,这题好玩啊。我写了N个小时,毕竟我是蒟蒻。
这是经典状压dp,但是我不会dp,什么都不会QAQ!!!
个人感觉啊,是图的话,基本都有一个遍历的过程,既然遍历了,那就是搜索了。能建图,一半都可以把答案搜出来,如果搜不出来,那一定是你打开的方式不对 =.=
废话扯完,讲题。
建图部分:
据说是离散化处理坐标,我不会。那就开map映射一下标号,就好了。这是一个单源有向隐式图,终点不确定。终点就是满足要求的点,多终点。单源最短路,鉴定完毕。
状压部分:
题目数据是5*5,所以一件商品数量上限是5,5==(101)b,所以记录商品的状态需要3*5=15个bit位。然后p<999; 25*p << 16 没有爆int,加上(1>>15)-1也没有爆,所以
可以直接用一个int 来存一个状态,状态包括物品的数量和当前的消耗。这时候再看这个题目,不久一个最短路么QAQ。然后你喜欢怎么写就怎么写咯。
PS:状态压缩后要保证能够准确地还原回去,不然那个压缩就没什么意义了
最短路部分:
图论很渣,但是dp我更渣。优先队列的自定义优先级,这是基本功啦。搜索终点是当前的各个商品的数量皆不小于目标数量,因为状态数是(1>>15)-1,这个大小的数组可以
妥妥的开,然后可以用这个数组来约束一下这个搜索,或者说就是一个剪枝吧,好吧,其实这就是dp(=.=)
注意一下,保证每个状态正确的更新,因为考虑到其实每个商品的数量是有可能可以大于7的,所以要实行数位拆分取模
还有就是注意自己写代码的姿势,习惯不一样,别越界,一定不要越界,千万别越界!越界就RE了,你丢掉了一些状态还是有可能A的,毕竟数据一般都有水。RE了就呵呵了
#include <iostream>#include <cstring>#include <map>#include <queue>using namespace std;int dp[1<<16];map<int, int> Map;int b, cnt, End, Edge[110];struct cmp { bool operator () (int a,int b) {return (a>>16) > (b>>16); }};void getdata(){int c, k, p, n, s;memset(Edge,0,sizeof Edge);cnt = 0;cin>> b;for (int item = 0;item < b; item++){cin>> c>> k>> p;Map[c] = item;End += k<< 3* item;Edge[ cnt ] += 1<< 3* item;Edge[cnt++] += p<< 16;}cin>> s;for (int edge = 0; edge < s; edge++){cin>> n;for( int j = 0; j < n; j++){cin>> c>> k;if(Map.count(c))Edge[cnt] += k<< 3* Map[c];}cin>> p;Edge[cnt] += p<<16;cnt++;}}int bfs(){memset(dp,0x3f,sizeof dp);priority_queue<int, vector<int> , cmp > Q;Q.push(0);while(!Q.empty()){int now = Q.top(); Q.pop();bool ok = true;for(int i = 0; i < b; i++){if( (now&(7<<3*i)) < (End&(7<<3*i)) ){ok = false;break;}}if(ok) return (now>>16);int next = 0;short next_pos;for (int i = 0; i < cnt; i++){next = now +Edge[i];next_pos = short(next);next -= next_pos;if(next_pos>=0 && dp[next_pos] > next){dp[next_pos] = next;for (int t= 0; t< b; t++){int tp = ((now&(7<<3*t)) +(Edge[i]&(7<<3*t)))%(7<<3*t);next += tp;}Q.push(next);}}}return 0;}int main(){ios_base::sync_with_stdio(false);getdata();cout<<bfs()<<endl;}
- POJ 1170 暴搜+dp剪枝优先队列+状压
- poj 2442 优先队列/堆+dp
- POJ 3184 DP+剪枝
- poj 3278 Catch That Cow 广度优先搜索 + 回溯 队列 剪枝
- hdu 5040 优先队列BFS+剪枝
- POJ 1442 优先队列
- POJ 1862 优先队列
- poj 3253 优先队列
- Poj 2010(优先队列)
- POJ 2442 优先队列
- POJ 2010 优先队列
- POJ 1862 优先队列
- 【优先队列】poj 2833
- poj 2970 优先队列
- POJ-3253-优先队列
- poj 2970 优先队列
- poj-3253 优先队列
- POJ 3253 (优先队列)
- OPENGL_三角形带GL_TRIANGLE_STRIP详解
- 2014华为机试(3)
- POJ 1631 Bridging signals(最长上升序列)
- 如何走好第一步
- myeclipse新手开发快捷键(更新中)
- POJ 1170 暴搜+dp剪枝优先队列+状压
- 利用.bat(批处理)来删除KEIL编译生成的无用文件
- 我在武汉新东方上过的8个老师
- python--有关函数的问题
- 黑马程序员——Java基础04(数组)
- UVALive - 4043 Ants (二分图最大权匹配)
- SDK学院--棱镜SDK:棱镜SDK 二次验证方案
- 『iOS/Obj-C』Note Of 8-day Obj-C/iOS foundation course
- JAVA基础——IO流知识点完整总结版