题目描述
Mr_H 旗下的 n 个 OIer 坐船外出旅行!
但是他们只有一艘船,虽然船能装下全部的 Oier,但太拥挤将会影响众 OIer 的心情,所以 Mr_H
决定选择一部分 Oier 去。我们假设,每个人单独坐船的快乐程度是 Ci,而船上每多一个人,他的
快乐程度会减去 Di。
现在你的任务是帮助 Mr_H 计算,选择那些人,才能使船上所有人的快乐程度之和达到最大。
输入
第 1 行是一个整数 n,表示 OIer 的人数;
第 2 行有 n 个整数,第 i 个整数表示第 i 个人人单独坐船的快乐程度 Ci(1<=Ci<=10000);
第 3 行有 n 个整数,第 i 个整数表示每多 1 人,第 i 个人快乐程度的下降值 Di(1<=Di<=10)。
输出
第 1 行一个整数,是最大的快乐程度之和;
第 2 行一个整数,是最大的快乐程度之和所对应的汽艇上的人数(若有多种方案,则输出人数最
多的)。
样例输入
6
10 10 10 10 10 9
2 2 2 2 2 3
样例输出
18
3
提示
前 3 个人去坐汽艇可使快乐程度之和达到最大,每个人的快乐程度均为 10-2*2=6,总和是 18。
对于 30%的数据,n<=20;
对于 100%的数据,n<=1000。
题解:枚举坐船人数i,按每个人此时的快乐程度由大到小排序,选择前i个快乐程度最大的人。
注意此题不可用dp,因为不满足最优子结构
#include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<algorithm> #include<queue> using namespace std; const int INF=0x3f3f3f3f; const int N=1010; int n, sum, sump; struct node{ int ha, dec; }peo[N]; priority_queue< int >q; int main() { scanf( "%d", &n ); for( int i=1; i<=n; i++ ) scanf( "%d", &peo[i].ha ); for( int i=1; i<=n; i++ ) scanf( "%d", &peo[i].dec ); sum=-INF; for( int i=1; i<=n; i++ ) { for( int j=1; j<=n; j++ ) q.push( peo[j].ha-peo[j].dec*(i-1) ); int j=1, ans=0; for( ; j<=i; j++ ) ans+=q.top(), q.pop(); for( ; j<=n; j++ ) q.pop(); if( sum<=ans ) { sum=ans; sump=i; } } printf( "%d\n%d\n", sum, sump ); return 0; }
[BZOJ2932]旅行
最新推荐文章于 2019-11-12 10:15:41 发布