1. 程式人生 > >X國的軍隊

X國的軍隊

題目描述
X 國和Y國開戰了!
作為 X 國的軍事參謀,你瞭解到事態的嚴峻性。為了更好地應付敵人,你收集到了城市
中n個據點的資訊,你打算攻破這 n個據點!

每個據點 i 的資訊由火力系數 A[i]、士兵數目 B[i]組成,作為一名具有高超預謀能力的謀,
你當然可以藉此分析情勢。實際上,你分析得出,攻佔一個據點 i,為了穩定己方士氣,
至少需要B[i]個士兵參戰,戰後將會有A[i]個士兵陣亡。由於不停地調譴,可用的士兵已
經不多了,於是在一個據點參戰且未陣亡的士兵可能會參加別的據點的戰鬥。你需要計
算出攻破這n個據點所需要的最少的士兵數目。

然而更糟的, 一共有 T個城市, 所以你需要將 T個城市所需的最少士兵數目依次輸出。

輸入格式
第一行為一個整數 T,表示城市數目。
接下來T組資料。每組資料第一行包含一個數 n,表示據點數目;接下來 n 行,其中
第i行包含兩個數,分別表示這個據點的火力系數A[i]以及士兵數目B[i]。

輸出格式
對於每個城市輸出一行,表示攻佔這個城市所有據點所需要的最少士兵數目。

樣例輸入
2
2
4 7
1 5
3
1 4
4 6
3 5

樣例輸出
8
10

資料範圍與約定
對於前20%的資料 n<=9
對於前40%的資料 n<=1000
對於100%的資料 n<=100000,T<=10,1<=A[i]<=B[i]<=1000000000。

由於本題讀入資料較多,建議使用較快的讀入方式。

題解

前20%的資料:大暴力,階乘列舉。
前40%的資料:暫時沒有想到這個範圍的做法,留出來供大家思考。
前100%的資料:
考慮倒著處理,那麼攻佔一個據點將會增加 A[i]的士兵數,且需要有(B[i]-A[i])個士兵
才可攻佔。又由於所有 A[i]的和為定值,於是顯然按(B[i]-A[i])從大到小排序,貪心處理即
可。

盡心盡力地寫了個假貪心四合一,然而發現隨機資料就可以卡掉這個假貪心…

附上程式碼

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<iostream>
using namespace std;
int T,n;
struct cza{int a,b,c;}x[100005];
int read()
{
    int x=0;char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
    return x;
}
bool cmp(cza x,cza y) {return x.c>y.c;}
int main()
{
    T=read();
    while(T--)
    {
        n=read();
        for(int i=1;i<=n;i++) x[i].a=read(),x[i].b=read(),x[i].c=x[i].b-x[i].a;
        sort(x+1,x+n+1,cmp);
        long long sum=0ll,p=0ll;
        for(int i=1;i<=n;i++)
        {
            if(x[i].b>=p) {sum+=x[i].b-p;p=0;}
            else p-=x[i].b;
            p+=x[i].b-x[i].a;
        }
        printf("%lld\n",sum);
    }
}

若您覺得此篇部落格寫得不錯,請別忘了點贊並關注我哦 >_<