hdu 4049 Tourism Planning [ 状压dp ]
传送门
Tourism Planning
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1115 Accepted Submission(s): 482
Each place they visited will cost every person certain amount of money. And each person has a positive value for each place, representing his or her interest in this place. To make things more complicated, if two friends visited a place together, they will get a non negative bonus because they enjoyed each other’s companion. If more than two friends visited a place together, the total bonus will be the sum of each pair of friends’ bonuses.
Your task is to decide which people should take the tourism and when each of them should leave so that the sum of the interest plus the sum of the bonuses minus the total costs is the largest. If you can’t find a plan that have a result larger than 0, just tell them to STAY HOME.
A case starting with 0 0 indicates the end of input and you needn’t give an output.
10
15
5
0 5
5 0
3 2
30 50
24 48
40 70
35 20
0 4 1
4 0 5
1 5 0
2 2
100 100
50 50
50 50
0 20
20 0
0 0
41
STAY HOME
| 13075053 | 2015-03-09 18:32:49 | Accepted | 4049 | 405MS | 2120K | 3076 B | G++ | czy |
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <string>
#define N 15 using namespace std; int n,m;
int p[N];
int v[N][N];
int b[N][N];
int dp[N][ (<<) ];
int ans;
int tot;
int happy[N][ (<<) ]; vector<int> can[ (<<) ]; int cal(int i,int o);
int ok(int k,int o); void ini()
{
int i,j;
ans=;
memset(dp,,sizeof(dp));
for(i=;i<=m;i++){
scanf("%d",&p[i]);
}
for(i=;i<n;i++){
for(j=;j<=m;j++){
scanf("%d",&v[i][j]);
}
}
for(i=;i<n;i++){
for(j=;j<n;j++){
scanf("%d",&b[i][j]);
}
}
int o;
tot = (<<n);
for(i=;i<=m;i++){
for(o=;o<tot;o++){
dp[i][o]=-;
}
}
//printf(" n=%d m=%d tot=%d\n",n,m,tot );
for(i=;i<=m;i++){
for(o=;o<tot;o++){
happy[i][o]=cal(i,o);
}
} for(o=;o<tot;o++){
can[o].clear();
for(int k=;k<tot;k++){
if(ok(k,o)==){
can[o].push_back(k);
}
}
}
} int cal(int i,int o)
{
int re=;
int j,k;
int cc=;
//printf(" i=%d o=%d\n",i,o );
for(j=;j<n;j++){
if( (<<j) & o ){
cc++;
re+=v[j][i];
}
}
//printf(" 1 re=%d\n",re );
for(j=;j<n;j++){
if( (<<j) & o ){
for(k=j+;k<n;k++){
if( (<<k) & o ){
re += b[j][k];
}
}
}
}
// printf(" 2 re=%d\n",re );
re -= p[i]*cc;
//printf(" 3 re=%d\n",re );
//printf(" i=%d o=%d re=%d\n",i,o,re );
return re;
} int ok(int k,int o){
int j;
for(j=;j<n;j++){
// printf(" j=%d\n",j );
if( (<<j) & o ){
if( ( (<<j) &k ) == ){
return ;
}
}
}
return ;
} void solve()
{
int o,j,i,k;
int te;
for(i=;i<=m;i++){
//printf(" i=%d\n",i );
for(o=;o<tot;o++){
// printf(" o=%d\n", o);
for(vector<int>::iterator it =can[o].begin();it != can[o].end();it++){
// for(k=0;k<tot;k++){
//printf(" k=%d\n", k);
k=*it;
// if(ok(k,o)==0) continue; //te=cal(i,o);
te=happy[i][o];
dp[i][o]=max(dp[i][o],dp[i-][k]+te);
//printf(" i=%d o=%d dp=%d\n", i,o,dp[i][o]);
}
}
} i=m;
for(o=;o<tot;o++){
//printf(" o=%d dp=%d\n",o,dp[m][o] );
ans=max(ans,dp[m][o]);
}
} void out()
{
if(ans<=){
printf("STAY HOME\n");
}
else{
printf("%d\n", ans);
}
} int main()
{
while(scanf("%d%d",&n,&m)!=EOF){
if(n== && m==) break;
ini();
solve();
out();
}
}
hdu 4049 Tourism Planning [ 状压dp ]的更多相关文章
- hdu 3247 AC自动+状压dp+bfs处理
Resource Archiver Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Ot ...
- hdu 2825 aC自动机+状压dp
Wireless Password Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- HDU 5765 Bonds(状压DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5765 [题目大意] 给出一张图,求每条边在所有边割集中出现的次数. [题解] 利用状压DP,计算不 ...
- hdu 3681(bfs+二分+状压dp判断)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 思路:机器人从出发点出发要求走过所有的Y,因为点很少,所以就能想到经典的TSP问题.首先bfs预 ...
- hdu 4778 Gems Fight! 状压dp
转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...
- hdu 4856 Tunnels (bfs + 状压dp)
题目链接 The input contains mutiple testcases. Please process till EOF.For each testcase, the first line ...
- HDU 4272 LianLianKan (状压DP+DFS)题解
思路: 用状压DP+DFS遍历查找是否可行.假设一个数为x,那么他最远可以消去的点为x+9,因为x+1~x+4都能被他前面的点消去,所以我们将2进制的范围设为2^10,用0表示已经消去,1表示没有消去 ...
- HDU 3362 Fix (状压DP)
题意:题目给出n(n <= 18)个点的二维坐标,并说明某些点是被固定了的,其余则没固定,要求添加一些边,使得还没被固定的点变成固定的, 要求总长度最短. 析:由于这个 n 最大才是18,比较小 ...
- HDU 3001 Travelling (状压DP,3进制)
题意: 给出n<=10个点,有m条边的无向图.问:可以从任意点出发,至多经过同一个点2次,遍历所有点的最小费用? 思路: 本题就是要卡你的内存,由于至多可经过同一个点2次,所以只能用3进制来表示 ...
随机推荐
- wkWebView 的一些问题
导语 WKWebView 是苹果在 WWDC 2014 上推出的新一代 webView 组件,用以替代 UIKit 中笨重难用.内存泄漏的 UIWebView.WKWebView 拥有60fps滚动刷 ...
- Scala基础篇-05求值策略
Scala的求值策略有2种: call by value call by name 如何区分? 例子: def bar(x:Int,y: => Int) = def loop(): Int=lo ...
- UVA 11020 Efficient Solutions (BST,Splay树)
题意:给n个坐标.一个坐标(x,y)若有无存在的坐标满足x1<x && y1<=y 或 x1<=x && y1<y 时,此坐标(x,y)是就 ...
- 什么是python 中的顶层代码?
在python语言中我们经常会听到顶层代码的说法,但是什么是顶层代码? 在python中,我们是以缩进来区分代码层次的,所以顶层代码指的是缩进为0个空格的代码. 看如下例子: PP = 3.14 de ...
- Python 使用re模块实现正则表达式
# coding: utf-8 # Team : Quality Management Center # Author:Carson # Date :2019/6/21 10:41 # Tool :P ...
- Python3中的输入输出
input()函数 我们可以通过Python3解释器查看Python3中input()的含义: >>> type(input) <class 'builtin_function ...
- Codeforces 1076D——最短路算法
题目 给你一个有n个顶点.m条边的无向带权图.需要擦除一些边使得剩余的边数不超过k,如果一个点在原始图到顶点1的最短距离为d,在删边后的图中到顶点的最短距离仍是d,则称这种点是 good.问如何删边, ...
- uva1627 Team them up!
注意这题要求互相认识不认识的人之间连一条线一个人在组1,那么不认识(互相认识)的人就在组0:同时这些人不认识的人就在组1.每个联通分量都可以独立推导,遇到矛盾则无解一个联通分量有一个核心,其他的点是分 ...
- MySQL存储过程实现分页及变量的定义
delimiter是MySQL中的命令,这个命令与存储过程没什么关系. 其实就是告诉mysql解释器,该段命令是否已经结束了,mysql是否可以执行了. 即改变输入结束符. 默认情况下,delimit ...
- iview 的 Carousel 走马灯 焦点图 不能用 建议换/vue-awesome-swiper
https://www.npmjs.com/package/vue-awesome-swiper