[NOIP模拟题]最佳旅行
2017-10-24 15:55
190 查看
Description
Bsny在杭州旅行,想去N个景点,于是他找来N个导游,每个导游负责带Bsny去一个景点玩一天,因此需要N个导游。这个N个导游对于N个景点有不同的熟悉度和喜爱度。为了旅游愉快,Bsny想尽量让每个导游可以去熟悉度和喜爱度最高的景点,但显然无法满足所有导游,因为Bsny希望想一种方案,使得每个导游的熟悉度总和与喜爱度总和之
积最大。你能告诉他最大能达到多少吗?
Input
第一行一个数N。
接下来一个N∗N的矩阵,其中元素Fi,j代表导游i对景点j的熟悉度。
接下来一个N∗N的矩阵,其中元素Li,j代表导游i对景点j的喜爱度。
N<=17,1<=Fi,j,Li,j<=1,000
Output
仅一行表示最大的熟悉度总和与喜爱度总和之积。
Sample Input
3
1 2 3
2 3 1
3 1 2
1 2 3
2 3 1
3 1 2
Sample Output
81
样例解释
1导游选择3景点,2导游选择2景点,3导游选择1景点。
于是熟悉度之和为(3+3+3)=9, 喜爱度之和为(3+3+3)=9, 积为9*9=81 这个是最大方案。
HINT
思路
这道题的数据范围很小,一定是搜索。但是一般的搜索会TLE,那么要想一些优化措施了,令fi,S表示选择了i个景点的状态为S的最大熟悉度之和,gi,S表示选择了i个景点的状态为S的最大喜爱度之和,如果当前选择的熟悉度之和为sumx,喜爱度之和为sumy,最终答案为ans,那么(sumx+fi,S)∗(sumy+gi,S)>=ans才可能更新答案,这样剪枝所得到的时间复杂度很低了。
代码
Bsny在杭州旅行,想去N个景点,于是他找来N个导游,每个导游负责带Bsny去一个景点玩一天,因此需要N个导游。这个N个导游对于N个景点有不同的熟悉度和喜爱度。为了旅游愉快,Bsny想尽量让每个导游可以去熟悉度和喜爱度最高的景点,但显然无法满足所有导游,因为Bsny希望想一种方案,使得每个导游的熟悉度总和与喜爱度总和之
积最大。你能告诉他最大能达到多少吗?
Input
第一行一个数N。
接下来一个N∗N的矩阵,其中元素Fi,j代表导游i对景点j的熟悉度。
接下来一个N∗N的矩阵,其中元素Li,j代表导游i对景点j的喜爱度。
N<=17,1<=Fi,j,Li,j<=1,000
Output
仅一行表示最大的熟悉度总和与喜爱度总和之积。
Sample Input
3
1 2 3
2 3 1
3 1 2
1 2 3
2 3 1
3 1 2
Sample Output
81
样例解释
1导游选择3景点,2导游选择2景点,3导游选择1景点。
于是熟悉度之和为(3+3+3)=9, 喜爱度之和为(3+3+3)=9, 积为9*9=81 这个是最大方案。
HINT
思路
这道题的数据范围很小,一定是搜索。但是一般的搜索会TLE,那么要想一些优化措施了,令fi,S表示选择了i个景点的状态为S的最大熟悉度之和,gi,S表示选择了i个景点的状态为S的最大喜爱度之和,如果当前选择的熟悉度之和为sumx,喜爱度之和为sumy,最终答案为ans,那么(sumx+fi,S)∗(sumy+gi,S)>=ans才可能更新答案,这样剪枝所得到的时间复杂度很低了。
代码
#include <cstdio> #include <algorithm> const int maxn=17; int n,f[maxn+2][1<<maxn],g[maxn+2][1<<maxn],ans; int x[maxn+1][maxn+1],y[maxn+1][maxn+1]; int dfs(int now,int s,int sumx,int sumy) { if(now>n) { ans=std::max(ans,sumx*sumy); return 0; } if((f[now][s]+sumx)*(g[now][s]+sumy)<ans) { return 0; } for(int i=1; i<=n; i++) { if(!(s&1<<(i-1))) { dfs(now+1,s|1<<(i-1),sumx+x[now][i],sumy+y[now][i]); } } return 0; } int main() { scanf("%d",&n); for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { scanf("%d",&x[i][j]); } } for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { scanf("%d",&y[i][j]); } } for(int i=n; i>0; i--) { for(int j=0; j<1<<n; j++) { for(int k=1; k<=n; k++) { if(!(j&(1<<(k-1)))) { f[i][j]=std::max(f[i][j],f[i+1][j|(1<<(k-1))]+x[i][k]); g[i][j]=std::max(g[i][j],g[i+1][j|(1<<(k-1))]+y[i][k]); } } } } dfs(1,0,0,0); printf("%d\n",ans); return 0; }
相关文章推荐
- 【原创】【重庆市NOIP2015模拟题】【CQBZOJ 2932】10.6第一题 旅行
- XJOI——NOIP2015提高组模拟题19-day1——观光旅行
- 【NOIP 模拟题】旅行(最短路)
- [NOIP2012]开车旅行
- (贪心)NOIP模拟题:引爆炸弹
- noip模拟题题解集
- NOIP模拟题 2016.11.4 [数论] [费马小定理] [最短路] [建图]
- 【动规递推】【120718测试】【NOIP模拟题】迷宫
- [NOIP模拟题][DFS][DP]
- 【NOIP 模拟题】[T2]拯救紫萱学姐(kmp+树形dp)
- [NOIP模拟题][树状数组][线段树]
- NOIP2001 Car的旅行路线
- 【noip2001 提高组T4】 Car的旅行路线 预处理+最短路
- 【NOIP模拟题】[状压dp][线段树]
- 【最短路】【NOIP2001】CAR的旅行路线
- 【NOIP模拟题】【模拟】【DP】【JOI】2016.11.14第一题 复制&粘贴2 题解
- NOIP模拟题 2016.11.15 [LIS] [spfa] [同余最短路] [矩阵快速幂] [容斥原理] [数学]
- 【NOIP模拟题】【DP】【LIS】【中缀表达式】2016.11.15 第一题 小L的二叉树 题解
- [noip模拟题]LGTB 玩THD
- 【NOIP 2012 开车旅行】***