【Mr.he原创】旅行

【问题描述】

  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。

考试第二题,拿到看到对象又有多个属性,以为是全排列生成,结果其实算个子集问题,每个人可以选上船或者不让他船。很简单暴力搜索O(2^n),30分。
优化:由于本题数据不算太大,故可以枚举上船的人数k,算出此时每个人的d[i],然后贪心排序后地选择前k大的数即可。每次选择完这些数,把他们累加到sum中,取sum的最大值就是答案。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#define maxn 1005
#define inf 1000000010
using namespace std;
int n;
struct data
{
    int c,d;
}A[maxn],B[maxn];

bool cmp(data a,data b)
{
    return a.c>b.c;
}

int main()
{
    //freopen("my.in","r",stdin);
    //freopen("my.out","w",stdout);

    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d",&A[i].c);

    for(int i=1;i<=n;i++)
    scanf("%d",&A[i].d);

    int maxa=0,maxc=0;
    for(int k=1;k<=n;k++)//枚举人数k 
    {
        int sum=0;
        memcpy(B,A,sizeof(A));
        for(int i=1;i<=n;i++)
        B[i].c-=(k-1)*B[i].d;

        sort(B+1,B+n+1,cmp);

        for(int i=1;i<=k;i++)
        sum+=B[i].c;

        maxa=max(maxa,sum);
        if(sum==maxa)maxc=max(maxc,k);
    }

    printf("%d\n%d\n",maxa,maxc);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值