http://www.lydsy.com/JudgeOnline/problem.php?id=3709php
在一款電腦遊戲中,你須要戰勝n只怪物(從1到n編號)。爲了戰勝第i只怪物,你須要消耗d[i]點生命值,但怪物死後會掉落血藥,使你恢復a[i]點生命值。任什麼時候候你的生命值都不能降到0(或0如下)。請問是否存在一種打怪順序,使得你能夠打完這n只怪物而不死掉c++
第一行兩個整數n,z(1<=n,z<=100000),分別表示怪物的數量和你的初始生命值。
接下來n行,每行兩個整數d[i],aispa
第一行爲TAK(是)或NIE(否),表示是否存在這樣的順序。
若是第一行爲TAK,則第二行爲空格隔開的1~n的排列,表示合法的順序。若是答案有不少,你能夠輸出其中任意一個。code
3 5遊戲
3 1get
4 8input
8 3it
TAKclass
2 3 1數據
看到數據範圍,其實就不像是個dp,應該就是貪心。
把怪物分紅兩種怪物,第一種是回覆>傷害的,咱們按照傷害從低到高去打就是最優的。
第二種是傷害>回覆的。咱們打完全部怪物的時候,血量必定是固定的,因此咱們先把把回血多的先殺掉,再殺回血少的。
#include<bits/stdc++.h> using namespace std; vector<pair<pair<int,int>,int> >p1,p2; vector<int> ans; bool cmp1(pair<pair<int,int>,int> A,pair<pair<int,int>,int> B){ return A.first.first<B.first.first; } bool cmp2(pair<pair<int,int>,int> A,pair<pair<int,int>,int> B){ return A.first.second<B.first.second; } int main(){ int n; long long z; scanf("%d%lld",&n,&z); for(int i=1;i<=n;i++){ pair<pair<int,int>,int> x; scanf("%d%d",&x.first.first,&x.first.second); x.second = i; if(x.first.first>=x.first.second){ p1.push_back(x); }else{ p2.push_back(x); } } sort(p1.begin(),p1.end(),cmp1); for(int i=0;i<p1.size();i++){ if(z<=p1[i].first.first){ cout<<"NIE"<<endl; return 0; }else{ z-=p1[i].first.first; z+=p1[i].first.second; ans.push_back(p1[i].second); } } sort(p2.begin(),p2.end(),cmp2); for(int i=p2.size()-1;i>=0;i--){ if(z<=p2[i].first.first){ cout<<"NIE"<<endl; return 0; }else{ z-=p2[i].first.first; z+=p2[i].first.second; ans.push_back(p2[i].second); } } cout<<"TAK"<<endl; for(int i=0;i<ans.size();i++){ cout<<ans[i]<<" "; } cout<<endl; }