POJ3045 牛的雜技(重慶一中高2018級信息學競賽測驗4) 解題報告

【問題描述】  
  
  FJ養了N頭牛,他們按照1到N依次編上了號。FJ所不知道的是,他的所有牛的夢想是從農場逃走,去參加馬戲團的演出。可奶牛門很快發現他們那麼笨拙的蹄子根本無法在鋼絲或晃動的鞦韆上站穩(他們還嘗試過把自己裝在大炮裏發射出去,但可想而知,結果是悲慘的)。最終,他們決定練習一種最簡單的雜技:把所有牛都摞在一起,比如說,第一頭牛站在第二頭牛的身上,同時第二頭牛有站在第三頭牛的身上……,最底下的是第N頭牛(牛果然沒什麼創造力)。 


  每頭牛都有自己的體重以及力量,編號爲i的牛的體重爲Wi,力量爲Si。當某頭牛身上站着另一些牛時它會在一定程度上被壓扁,我們不妨把它被壓扁的程度叫着壓扁指數。對於任意的牛,它的壓扁指數等於摞在它上面所有牛的總重量(當然不包括自己)減去它的力量。奶牛們按照一定的順序摞在一起後,他們的總壓扁指數就是被壓得最扁的那頭牛的壓扁指數。你的任務就是幫助奶牛們找出一個摞在一起的順序,使得總壓扁指數最小。
 
    
 【輸入格式】  
  
  第 1 行:一個單獨的正整數N。
  第  2到第 N+1 行:第 i+1 行給出編號爲i的奶牛的體重於力量 Wi 和 Si ,用一個空格分開。


 
    
 【輸出格式】  
   
  一個整數,表示奶牛門總壓扁指數的最小值。
 
    
 【輸入樣例】   
   
3
10 3
2 5
3 3
 
    
 【輸出樣例】  
   
2
 
    
 【樣例解釋】  
   
把重量爲10的那頭牛放在最底下,於是她的壓扁指數就是2+3-3=2。其他2頭牛的壓扁指數都小於這個值。
 
    
 【數據範圍】  
   
1<=N<=50 000  1<=Wi<=10 000   1<=Si<=1 000 000 000
 
    
 【來源】  
  

poj 3045


做題思路(正解):本題的主要算法是貪心算法,先將所有奶牛按放在最底層時的壓扁指數由大到小排序(其實還有另外的排序方法),則貪心策略爲選擇放在最底層時壓扁指數最大的放在最上面,然後從第一頭奶牛開始依次枚舉每i頭奶牛,放在第i-1頭奶牛的下面,計算當前奶牛的壓扁指數,答案即爲每頭奶牛壓扁指數的最大值。


解題思路(正解):在老師給的解法中,實現排序時給出了另外一種方法,設Aij爲先選第i頭奶牛再選第j頭奶牛的最大壓扁指數,Aji爲先選第j頭奶牛再選第i頭奶牛的最大壓扁指數,設i和j之前選的奶牛的重量和爲sum,則Aij=max(sum-a[i].s,sum+a[i].w-a[j].s),Aji=max(sum-a[j].s,sum+a[j].w-a[i].s),兩邊同時減去sum,則Aij=max(-a[i].s,a[i].w-a[j].s),Aji=max(-a[j].s,a[j].w-a[i].s),返回值小的,然後從第一頭奶牛開始枚舉第i頭奶牛,依次放在第i-1頭奶牛的下面,計算出最大的壓扁指數。(此方法的代碼請見POJ3045 牛的雜技 from cqyz_yuyuko


#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=50005;
const int inf=1000000010;
int N,sum=0;
struct data
{
	int w,s;
};
data a[maxn];
bool cmp(data aa,data bb)
{
	return sum-aa.w-aa.s>sum-bb.w-bb.s;
}
int main()
{
	freopen("cow.in","r",stdin);
	freopen("cow.out","w",stdout);
	scanf("%d",&N);
	for(int i=1;i<=N;i++)
	{
		scanf("%d%d",&a[i].w,&a[i].s);
		sum+=a[i].w;  //計算所有奶牛的重量和 
	}
	sort(a+1,a+1+N,cmp); //按每頭奶牛在最底層的壓扁指數由大到小排序 
	int ret=0,ans=-inf;
	for(int i=1;i<=N;i++)
	{
		int t=ret-a[i].s;  //計算當前奶牛的壓扁指數 
		ans=max(ans,t);
		ret+=a[i].w;  //計算當前重疊在上面的奶牛的重量和 
	}
	printf("%d\n",ans);
	return 0;
}

考後反思:也許比較函數的寫法會有很多種,不要選擇最簡單的,要選擇自己最熟悉和最有把握的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章