zcmu1059: 田忌賽馬 貪心演算法
1059: 田忌賽馬
時間限制: 1 Sec 記憶體限制: 128 MB提交: 1303 解決: 347
[提交][狀態][討論版]
題目描述
田忌和齊王賽馬,兩人各出n匹馬,贏一場比賽得200兩銀子,輸了賠200銀子,平局不賠不賺.已知兩人每匹馬的速度,問田忌最多能贏多少銀子.
輸入
多組測試資料,
每組資料的第一行是一個整數n。 (1<=n<=1000)
第二行包括n個整數既田忌每匹馬的速度.
第三行包括n個整數既齊王每匹馬的速度.
每匹馬的速度不超過1000.
輸出
對於每組資料輸出一行有一個整數代表田忌最多能贏多少銀子
樣例輸入
392 83 71 95 87 74 2 20 20 20 20 2 20 19 22 18樣例輸出
20大一進來不久的時候第一次做了這個題目,結果給這個題目擺了一道,研究了半天沒懂,後來就對這個貪心演算法心生恐懼。
現在準備正式攻略一下。
先轉載一段貪心演算法的定義和核心:點選開啟連結
貪心演算法是指在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,只做出在某種意義上的區域性最優解。貪心演算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關。
解題的一般步驟是:
1.建立數學模型來描述問題;
2.把求解的問題分成若干個子問題;
3.對每一子問題求解,得到子問題的區域性最優解;
4.把子問題的區域性最優解合成原來問題的一個解。
說白了就是在把問題分開每一步都取最優解,這就是貪心。這應該就是要求他每一步都不會影響後面的問題以及整體。也就是和全域性最優解相對的區域性最優解。這也就是貪心演算法的限制條件了。
第一次看到貪心演算法 感覺就是很普通很簡單的演算法 完全是一種理論 但是因為它沒有固定的模板 想去熟練掌握還真的很麻煩。
回到這個題目吧,用貪心演算法,首先先用sort函式把兩隊的馬的速度進行排序,之後列一個具體的思路:
1.首先用最慢的比,如果田忌最慢的馬比齊王最慢的馬快,那麼贏一場。
2.如果田忌最快的馬比齊王最快的馬快,也贏一場。
3.如果田忌最慢的馬比齊王最慢的馬慢或者最快的比最快的慢,那麼田忌最慢的幹齊王最快的,
4,如果田忌最慢的馬比齊王最慢的馬慢或者最快的比最快的慢且
貼程式碼:
#include<bits/stdc++.h>
using namespace std;
int i,j,la,lb,n,a[1010],b[1010],sum;
bool cmp(int a,int b){
return a>b;
}
int main(){
while(cin>>n){
for(i=0;i<n;i++)cin>>a[i];
for(i=0;i<n;i++)cin>>b[i];
sort(a,a+n,cmp);
sort(b,b+n,cmp);
for(i=j=sum=0,la=lb=n-1;i<=la;){
if(a[la]>b[lb])sum++,la--,lb--;
else if(a[i]>b[j])sum++,i++,j++;
else {
if(a[la]!=b[j])sum--;
la--,j++;
}
}
cout<<sum*200<<endl;
}
return 0;
}