[NOIP2012提高组]国王游戏
題目:洛谷P1080、Vijos P1779、codevs1198。
題目大意:國王和每個大臣左、右手各寫了一個數。規定每個大臣得到的金幣數為他前面所有人左手的數字的乘積除以他自己右手的數(向下取整),現在國王要改變大臣的排列順序,使得獲得獎賞最多的大臣,所獲獎賞盡可能的少(國王永遠站在最前面)。
解題思路:(貪心)首先,交換相鄰兩個大臣只會對這兩個大臣造成影響,并不會對其他大臣造成影響。
我們考慮大臣i和i+1,設他們左手數字分別為A[i]和A[i+1],右手分別為B[i]和B[i+1],前i-1個大臣和國王左手的數的乘積為S,且A[i]B[i]<=A[i+1]B[i+1]。
原來兩個大臣能得到的金幣數分別為S/B[i],S*A[i]/B[i+1]。
如果交換,則第一個大臣現在能得到S*A[i+1]/B[i],第二個能得到S/B[i+1]。
由于A[i]B[i]<=A[i+1]B[i+1],所以S*A[i]*B[i]<=S*A[i+1]*B[i+1],所以S*A[i]/B[i+1]<=S*A[i+1]/B[i]。
由此可得大臣以A[i]B[i]從小到大排序,答案越小。
而S*A[i+1]/B[i]>=S/B[i],S*A[i]/B[i+1]>=S/B[i+1],故最大的答案為后面那個大臣的,也保證了答案的正確性。
然后高精度一下就好了。
C++ Code:
#include<cstdio> #include<cstring> #include<iostream> #include<string> #include<vector> #include<algorithm> using namespace std; struct BigInteger {static const int BASE=100000000;static const int WIDTH=8;vector<long long>s;BigInteger(long long num=0){*this=num;}BigInteger operator = (long long num){s.clear();do{s.push_back(num%BASE);num/=BASE;} while(num>0);return *this;}BigInteger operator = (const string& str){s.clear();int x,len=(str.length()-1)/WIDTH+1;for(int i=0;i<len;i++){int end=str.length()-i*WIDTH;int start=max(0,end-WIDTH);sscanf(str.substr(start,end-start).c_str(),"%d",&x);s.push_back(x);}return *this;}BigInteger operator + (const BigInteger& b)const{BigInteger c;c.s.clear();for(int i=0,g=0;;i++){if(g==0&&i>=s.size()&&i>=b.s.size())break;int x=g;if(i<s.size())x+=s[i];if(i<b.s.size())x+=b.s[i];c.s.push_back(x%BASE);g=x/BASE;}return c;}bool operator < (const BigInteger& b)const{if(s.size()!=b.s.size())return s.size()<b.s.size();for(int i=s.size()-1;i>=0;i--)if(s[i]!=b.s[i])return s[i]<b.s[i];return false;}bool operator > (const BigInteger& b)const{return b<*this;}bool operator <= (const BigInteger& b)const{return !(b<*this);}bool operator >= (const BigInteger& b)const{return !(*this<b);}bool operator != (const BigInteger& b)const{return b<*this||*this<b;}bool operator == (const BigInteger& b)const{return !(b<*this)&&!(*this<b);}void cheng(int a){vector<long long>c;for(int i=0;i<s.size();++i){if(c.size()<=i)c.push_back(s[i]*a);elsec[i]+=s[i]*a;if(c[i]/BASE)if(c.size()<=i+1)c.push_back(c[i]/BASE);elsec[i+1]=c[i]/BASE;c[i]%=BASE;}s=c;}void chu(int a){vector<long long>c(s);if(s.back()/a)c[s.size()-1]=s.back()/a,s[s.size()-1]%=a;elsec.pop_back();for(int i=s.size()-2;i>=0;--i){long long num=s[i+1]*BASE+s[i];c[i]=num/a;num%=a;s[i]=num;}s=c;} }; ostream& operator << (ostream &out,const BigInteger& x){out<<x.s.back();for(int i=x.s.size()-2;i>=0;i--){char buf[20];sprintf(buf,"%08d",x.s[i]);for(int j=0;j<strlen(buf);j++)out<<buf[j];}return out; } istream& operator >> (istream &in,BigInteger& x){string s;if(!(in>>s))return in;x=s;return in; } struct DC{int a,b;bool operator < (const DC&rhs)const{return a*b<rhs.a*rhs.b;} }p[1005]; int n; BigInteger sum,Div,ans; int main(){ios::sync_with_stdio(false);cin>>n;for(int i=0;i<=n;++i)cin>>p[i].a>>p[i].b;sort(p+1,p+n+1);sum=ans=p[0].a;for(int i=1;i<=n;++i){Div=sum;Div.chu(p[i].b);if(ans<Div)ans=Div;sum.cheng(p[i].a);}cout<<ans<<endl;return 0; }?
轉載于:https://www.cnblogs.com/Mrsrz/p/7545044.html
總結
以上是生活随笔為你收集整理的[NOIP2012提高组]国王游戏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS-WEB-API(存储)
- 下一篇: 我的编程成长之路——python初体验