[hdu4940]Tourism Planning 状态压缩DP
2016-11-21 23:23
295 查看
题目描述
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.
算法思路
其实状态压缩的想法是很简单的,因为奖励值需要我们知道在具体的状态之下到底存在哪些人,所以我们定义dp[i][j]为人员状态为j的时候到达i地点所可以得到的最优值.在每一步当中,都会离开一些人,人数未知,但是离开的人不会再回来,所以,我们得到的动态规划状态转移方程如下所示:DP[i][j]=max(DP[i][t]+w),for every t that t&k=k
2.但是,这里要注意初始化的问题,我们在进行初始化的时候要将值定义为无穷小,只有这样才不会失去后效性,因为在上一步算出来的最优值是存在可能是一个负数的。
代码
#include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; #define MAXN 2050 const int INF = 1<<30; int dp[11][MAXN]; int n,m; int bonus[11][11]; int cost[11],interest[11][11]; int sumbonus[MAXN]; int sumpeople[MAXN]; int suminterest[11][MAXN]; void Solve() { int i,j,k,t; int ans = 0; memset(sumbonus,0,sizeof(sumbonus)); memset(sumpeople,0,sizeof(sumpeople)); memset(suminterest,0,sizeof(suminterest)); memset(dp,0,sizeof(dp)); for(i=0;i<(1<<n);i++) dp[0][i] = -INF; for(i=0;i<(1<<n);i++){ for(j=0;j<n;j++){ if(i&(1<<j)){ sumpeople[i]++; for(k=j+1;k<n;k++){ if(i&(1<<k)) sumbonus[i] += bonus[j][k]; } } } } for(i=0;i<m;i++){ for(j=0;j<(1<<n);j++){ for(k=0;k<n;k++){ if(j&(1<<k)) suminterest[i][j] += interest[k][i]; } } } for(i=0;i<(1<<n);i++){ dp[0][i] = suminterest[0][i]+sumbonus[i]-sumpeople[i]*cost[0]; } for(i=1;i<m;i++){ for(k=0;k<(1<<n);k++){ dp[i][k] = dp[i-1][k]; for(t=0;t<(1<<n);t++){ if((t&k)==k && dp[i-1][k]>-INF) dp[i][k] = max(dp[i][k],dp[i-1][t]+sumbonus[k]-sumpeople[k]*cost[i]+suminterest[i][k]); } } } for(i=0;i<(1<<n);i++) ans = max(ans,dp[m-1][i]); if(ans>0)printf("%d\n",ans); else printf("STAY HOME\n"); return; } int main() { freopen("input","r",stdin); int i,j; while(1){ scanf("%d%d",&n,&m); if(!n&&!m)break; for(i=0;i<m;i++) scanf("%d",&cost[i]); for(i=0;i<n;i++){ for(j=0;j<m;j++) scanf("%d",&interest[i][j]); } for(i=0;i<n;i++){ for(j=0;j<n;j++) scanf("%d",&bonus[i][j]); } Solve(); } return 0; }
相关文章推荐
- light oj 1057 Collecting Gold(状态压缩dp)
- Vijos 1193 扫雷(状态压缩DP)
- UVA 10817-Headmaster’s Headache(状态压缩DP)
- HDU4336——期望+状态压缩DP——Card Collector
- Codeforces Round 580 D. Kefa and Dishes (状态压缩dp)
- HDU1565方格取数(1)(状态压缩DP)
- CEOI 2002, POJ 1038 Bugs Integrated, Inc. 状态压缩 DP
- POJ 3254 Corn Fields 状态压缩dp入门
- POJ 2441 Arrange the Bulls 状态压缩递推简单题 (状态压缩DP)
- 【连通性状态压缩DP】UVA10572Black&White
- poj 1185 炮兵阵地 【状态压缩dp】
- POJ1185 炮兵阵地 状态压缩DP
- hdu 4778 Gems Fight!【状态压缩,记忆化搜索dp】
- HDU 4284 Travel【状态压缩DP】
- 状态压缩DP-棋盘模型总结
- 状态压缩 dp 杭电1074
- HDU1074 Doing Homework 状态压缩dp
- ZOJ 3502 Contest (状态压缩+DP , py大法好)
- HDU1074 Doing Homework 状态压缩dp
- POJ 1185 炮兵阵地(状态压缩DP)