传送门

Tourism Planning

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1115    Accepted Submission(s): 482

Problem Description
Several friends are planning to take tourism during the next holiday. They have selected some places to visit. They have decided which place to start their tourism and in which order to visit these places. However, anyone can leave halfway during the tourism and will never back to the tourism again if he or she is not interested in the following places. And anyone can choose not to attend the tourism if he or she is not interested in any of the places.
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.
 
Input
There are several cases. Each case starts with a line containing two numbers N and M ( 1<=N<=10, 1<=M<=10). N is the number of friends and M is the number of places. The next line will contain M integers Pi (1<=i<=M) , 1<=Pi<=1000, representing how much it costs for one person to visit the ith place. Then N line follows, and each line contains M integers Vij (1<=i<=N, 1<=j<=M), 1<=Vij<=1000, representing how much the ith person is interested in the jth place. Then N line follows, and each line contains N integers Bij (1<=i<=N, 1<=j<=N), 0<=Bij<=1000, Bij=0 if i=j, Bij=Bji.
A case starting with 0 0 indicates the end of input and you needn’t give an output.
 
Output
For each case, if you can arrange a plan lead to a positive result, output the result in one line, otherwise, output STAY HOME in one line.
 
Sample Input
2 1
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
 
Sample Output
5
41
STAY HOME
 
Source
 
Recommend
lcy   |   We have carefully selected several similar problems for you:  4041 4043 4050 4044 4045 
 
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 ]的更多相关文章

  1. hdu 3247 AC自动+状压dp+bfs处理

    Resource Archiver Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Ot ...

  2. hdu 2825 aC自动机+状压dp

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  3. HDU 5765 Bonds(状压DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5765 [题目大意] 给出一张图,求每条边在所有边割集中出现的次数. [题解] 利用状压DP,计算不 ...

  4. hdu 3681(bfs+二分+状压dp判断)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 思路:机器人从出发点出发要求走过所有的Y,因为点很少,所以就能想到经典的TSP问题.首先bfs预 ...

  5. hdu 4778 Gems Fight! 状压dp

    转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...

  6. hdu 4856 Tunnels (bfs + 状压dp)

    题目链接 The input contains mutiple testcases. Please process till EOF.For each testcase, the first line ...

  7. HDU 4272 LianLianKan (状压DP+DFS)题解

    思路: 用状压DP+DFS遍历查找是否可行.假设一个数为x,那么他最远可以消去的点为x+9,因为x+1~x+4都能被他前面的点消去,所以我们将2进制的范围设为2^10,用0表示已经消去,1表示没有消去 ...

  8. HDU 3362 Fix (状压DP)

    题意:题目给出n(n <= 18)个点的二维坐标,并说明某些点是被固定了的,其余则没固定,要求添加一些边,使得还没被固定的点变成固定的, 要求总长度最短. 析:由于这个 n 最大才是18,比较小 ...

  9. HDU 3001 Travelling (状压DP,3进制)

    题意: 给出n<=10个点,有m条边的无向图.问:可以从任意点出发,至多经过同一个点2次,遍历所有点的最小费用? 思路: 本题就是要卡你的内存,由于至多可经过同一个点2次,所以只能用3进制来表示 ...

随机推荐

  1. 网页尺寸scrollHeight/offsetHeight

    scrollHeight和scrollWidth,获取网页内容高度和宽度. 一.针对IE.Opera: scrollHeight 是网页内容实际高度,可以小于 clientHeight. 二.针对NS ...

  2. BottomNavigationBar底部导航条用法

    先来张效果图 接下来是实现过程 1.加入依赖 compile 'com.ashokvarma.android:bottom-navigation-bar:1.3.0' 2.xml布局 fragment ...

  3. 洛谷 P1548 棋盘问题

    题目描述 设有一个N*M方格的棋盘(l<=N<=100,1<=M<=100)(30%) 求出该棋盘中包含有多少个正方形.多少个长方形(不包括正方形). 例如:当 N=2, M= ...

  4. 洛谷 P1832 A+B Problem(再升级)

    题目背景 ·题目名称是吸引你点进来的 ·实际上该题还是很水的 题目描述 ·1+1=? 显然是2 ·a+b=? 1001回看不谢 ·哥德巴赫猜想 似乎已呈泛滥趋势 ·以上纯属个人吐槽 ·给定一个正整数n ...

  5. pylint安装失败的解决方法

    原文链接http://www.cnblogs.com/Loonger/p/7815335.html 使用命令pip3 install pylint安装pylint是出现错误.查了一圈也找不到答案.仔细 ...

  6. 1-1 编程基础 GCC程序编译

    GCC简介      Linux系统下的gcc是GNU推出的强大.性能优越的多平台编译器,是GNU的代表作之一.gcc可以在多种硬体平台上编译出可执行程序,其执行效率与一般的编译器相比平局效率要高20 ...

  7. PHP 中空字符串介绍0、null、empty和false之间的关系

    0是数字,是empty,是false,不是null,值相当于空字符串,但类型不是字符串,去空格或强制转换为字符串型时不等于空字符串 ""的值相当于0,是empty,是空字符串,是f ...

  8. 部署 k8s Cluster(上)[转]

    我们将部署三个节点的 Kubernetes Cluster. k8s-master 是 Master,k8s-node1 和 k8s-node2 是 Node. 所有节点的操作系统均为 Ubuntu ...

  9. CAD交互绘制矩形框(网页版)

    主要用到函数说明: _DMxDrawX::DrawLine 绘制一个直线.详细说明如下: 参数 说明 DOUBLE dX1 直线的开始点x坐标 DOUBLE dY1 直线的开始点y坐标 DOUBLE ...

  10. 1.1 Qt入门

    学习Qt的前提是学好C++. 我刚入门Qt,打算趁着暑假2个月时间来学习<C++ GUI Qt 4>这本书. 现在有Qt4和Qt5,似乎很多公司都还是在使用Qt4,所以我也就选择了学习Qt ...