【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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章