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); } }
若您覺得此篇部落格寫得不錯,請別忘了點贊並關注我哦 >_<