状态压缩DP----HDU4049 Tourism Planning
状态压缩动态规划感觉都不是那么好写,看网上的人说这题是2011年ACM/ICPC中的水题,暗地里感觉很是惭愧啊(花了将近4个小时),结果还算是勉勉强强地弄出来了。
与往常一样,先说说题目的意思和思路,再给出代码,最后分享出代码比较精髓的地方(有的话),另这随笔主要目的是方便自己以后使用,当然很是欢迎大家指出错误和批评。那就开始了:
题目说的是有一群小伙伴去旅游,某个人对某以特定的城市有一定的兴趣,并且多人一同去还有奖励,当然门票还是要的嘛。
输入:N(小伙伴的个数),M(城市的个数)紧接着的一行是各个城市的门票价格,然后是一个N*M的矩阵表示第i名游客对j城市的感兴趣度,最后还有一个N*N的矩阵表示若i旅客与j旅客结伴出行的话可以得到的奖金。特别注意的是游客可以中间插入,也可以中途离开,但若是中途离开以后就不得在后面的观光中出现.
输出:最后的结果若<=0,那么就输出"STAY HOME"。
思路还是状态压缩嘛,具体来讲就是用一个叫DP[i]的数组记录从开始的城市到当前城市中总共值中选出最大的,在用一个temp[i]数组来保存相应的DP[i]值,为后面的DP做准备,然后交替进行,期间必须保证离队以后的人不可以再次入队,这点怎么保证呢?
for(int i=1;i<=M;i++)
{
for(int j=0;j<bit;j++) dp[j]=MIN;
for(int j=0;j<bit;j++)
{
int weight=calculate(j,i);
for(int k=j;k<bit;k=(k+1)|j)
{
dp[j]=max(dp[j],temp[k]+weight);
}
}
for(int j=0;j<bit;j++) temp[j]=dp[j];
}
就用这几行代码就可以搞定了。第一个for循环是从1到M的城市,第二行是对于城市i的状态为j,第三行是总结出从1到i可以达到的最大值,中间的temp一直记录这些最大值,这与滚动数组非常类似。为什么这样写就能保证中途掉队的的在以后就一定加不进来呢?那么你可以仔细看看第三个for循环k是如何增加的(k=(k+1)|j)保证了变化后的k中一定包含有j的状态,也就是说参观第i-1座城市的人一定>=参观i城市时候的人,并且i城市的人在i-1城市的一定有,然后大家可以用类似于归纳法的思想来证明这种思路是正确的。
不罗嗦了,直接上代码:
#include <iostream>
#include <cstdio>
#include <cstring> using namespace std;
#define INFI (1<<10)+20
#define MIN -2139062144
int N,M;
int dp[INFI],bonus[][],cost[];
int inter[][],temp[INFI]; inline int max(int a,int b)
{
if(a>b) return a;
return b;
}
int calculate(int k,int v)
{
int sieze[],num=,result=;
for(int i=;i<N;i++) if(k&(<<i)) sieze[++num]=i;
for(int i=;i<=num;i++)
{
result+=inter[sieze[i]][v];
for(int j=i+;j<=num;j++) result+=bonus[sieze[i]][sieze[j]];
}
return result-num*cost[v];
}
int DP()
{
int bit=<<N;
for(int i=;i<bit;i++) temp[i]=;
for(int i=;i<=M;i++)
{
for(int j=;j<bit;j++) dp[j]=MIN;
for(int j=;j<bit;j++)
{
int weight=calculate(j,i);
for(int k=j;k<bit;k=(k+)|j)
{
dp[j]=max(dp[j],temp[k]+weight);
}
}
for(int j=;j<bit;j++) temp[j]=dp[j];
}
int result=-;
for(int i=;i<bit;i++) result=max(result,temp[i]);
if(result<=) printf("STAY HOME.\n");
else printf("%d\n",result);
}
int main()
{ while(scanf("%d %d",&N,&M),(N||M))
{
for(int i=;i<=M;i++)
scanf("%d",&cost[i]); for(int i=;i<N;i++)
for(int j=;j<=M;j++)
scanf("%d",&inter[i][j]); for(int i=;i<N;i++)
for(int j=;j<N;j++)
scanf("%d",&bonus[i][j]); DP();
} return ;
}
状态压缩DP----HDU4049 Tourism Planning的更多相关文章
- HOJ 2226&POJ2688 Cleaning Robot(BFS+TSP(状态压缩DP))
Cleaning Robot Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4264 Accepted: 1713 Descri ...
- hoj2662 状态压缩dp
Pieces Assignment My Tags (Edit) Source : zhouguyue Time limit : 1 sec Memory limit : 64 M S ...
- POJ 3254 Corn Fields(状态压缩DP)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4739 Accepted: 2506 Descr ...
- [知识点]状态压缩DP
// 此博文为迁移而来,写于2015年7月15日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6jf.html 1.前 ...
- HDU-4529 郑厂长系列故事——N骑士问题 状态压缩DP
题意:给定一个合法的八皇后棋盘,现在给定1-10个骑士,问这些骑士不能够相互攻击的拜访方式有多少种. 分析:一开始想着搜索写,发现该题和八皇后不同,八皇后每一行只能够摆放一个棋子,因此搜索收敛的很快, ...
- DP大作战—状态压缩dp
题目描述 阿姆斯特朗回旋加速式阿姆斯特朗炮是一种非常厉害的武器,这种武器可以毁灭自身同行同列两个单位范围内的所有其他单位(其实就是十字型),听起来比红警里面的法国巨炮可是厉害多了.现在,零崎要在地图上 ...
- 状态压缩dp问题
问题:Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Ev ...
- BZOJ-1226 学校食堂Dining 状态压缩DP
1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec Memory Limit: 259 MB Submit: 588 Solved: 360 [Submit][ ...
- Marriage Ceremonies(状态压缩dp)
Marriage Ceremonies Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu ...
- HDU 1074 (状态压缩DP)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:有N个作业(N<=15),每个作业需耗时,有一个截止期限.超期多少天就要扣多少 ...
随机推荐
- BROCADE交换机配置
BROCADE交换机配置一 与交换机交互,可以使用三种方式: 串口 以太网口 光纤口 缺省的串口参数是:9600,N,8,1 缺省IP访问方式是: IP地址: 10.77.77.77 用户名: adm ...
- codeforces 985 D. Sand Fortress(二分+思维)
Sand Fortress time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- POJ_3740 Easy Finding ——精确覆盖问题,DLX模版
Easy Finding Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 18790 Accepted: 5184 Des ...
- Java-Maven-Runoob:Maven教程
ylbtech-Java-Maven-Runoob:Maven教程 1.返回顶部 1. Maven 教程 Maven 翻译为"专家"."内行",是 Apache ...
- Vue.js:template
ylbtech-Vue.js: 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 7.返回顶部 8.返回顶部 9.返回顶部 1 ...
- Java学习之Dubbo+ZooKeeper分布式服务Demo
背景:在之前的一个<Java学习之SpringBoot整合SSM Demo>分享中说到搭建ZooKeeper和Dubbo分布式框架中遇到了一些技术问题没能成功,只分享了其中的一个中间产物, ...
- Py修行路 python基础 (十)装饰器
装饰器 一.定义 装饰器:顾名思义,就是对某个东西起到装饰修饰的功能. python中的装饰器,其本质上就是一个python函数,它可以让其他函数在不需要任何代码变动的前提下增加额外功能.通俗理解就是 ...
- Py修行路 python基础 (十七)property 静态方法 类方法
一.property 属性 特性 (装饰器是可调用对象,被装饰对象也是可调用对象) 1.在类内函数属性上添加一个@property,就会对函数属性进行伪装. import math class C ...
- javascipt——原型
1.原型存在的意义 JS不是面向对象的语言,没有类的概念,但是提供了构造器函数,其也可以创建一个对象.构造器函数如下: function people(name, age, sex) { this.n ...
- C#递归所以部门展示到TreeView
C#递归所以部门展示到TreeView 1.首先是数据库表的设计 新建一张部门表:TestUser表 1.ID自增int主键 2.DeptName:nchar(10)3.DeptCode:nchar( ...