一道非常有挑战性的题目(~太难了~)。
这题我们可以用贪心来做。
思路:
- 首先我们定义一个结构体 struct,里面放的是每个人左手和右手的数字。
- 接着我们需要一种排列方式,使得获得奖赏最多的大臣,所获奖赏尽可能的少;这句话听起来是不是听绕口?意思就是说得到奖赏数量最多,但加起来的总奖赏和最少;因此,我们可以定义一个自定义排序 cmp,使 a.l*a.r<b.l*b.r。
- 我们可以在定义两个 vector 数组 ans 和 t,ans 第 0 个值初始化成0,t 第 0 个值初始化成 1。
- 随后是高精度乘低精度和高精度除以低精度的函数。
- 最后再定义一个函数 compare,用来比较大小。
- 输入,注意:要先输入 f[0].l 和 f[0].r,表示国王的左手和右手。
AC CODE:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
struct stu{
int l;
int r;
}f[1005];
bool cmp(stu a,stu b){
return a.l*a.r<b.l*b.r;
}
int n;
vector<int> ans(1,0);
vector<int> t(1,1);
inline vector<int> mul(vector<int> &a,int b){
vector<int> res;
int t = 0;
int len = a.size();
for(int i=0;i<len;i++){
t+=a[i]*b;
res.push_back(t%10);
t/=10;
}
while(t){
res.push_back(t%10);
t/=10;
}
return res;
}
inline vector<int> div(vector<int> &a,int b){
vector<int> res;
int r = 0;
int len = a.size();
for(int i=len-1;i>=0;i--){
r = 10*r+a[i];
if(r>=b){
res.push_back(r/b);
r%=b;
}else{
res.push_back(0);
}
}
vector<int> cnt;
len = res.size();
for(int i=len-1;i>=0;i--){
cnt.push_back(res[i]);
}
while((cnt.back()==0)&&(cnt.size()>1)){
cnt.pop_back();
}
return cnt;
}
inline int compare(vector<int> &a,vector<int> &b){
int lenA = a.size();
int lenB = b.size();
if(lenA!=lenB){
int t = lenA-lenB;
return t;
}else{
for(int i=lenA-1;i>=0;i--){
if(a[i]!=b[i]){
int t = a[i]-b[i];
return t;
}
}
return 0;
}
}
int main(){
cin>>n;
cin>>f[0].l>>f[0].r;
for(int i=1;i<=n;i++){
cin>>f[i].l>>f[i].r;
}
sort(f+1,f+1+n,cmp);
t = mul(t,f[0].l);
for(int i=1;i<=n;i++){
vector<int> res = div(t,f[i].r);
if(compare(ans,res)<0){
ans = res;
}
t = mul(t,f[i].l);
}
int len = ans.size();
for(int i=len-1;i>=0;i--){
cout<<ans[i];
}
cout<<endl;
return 0;
}
标签:cnt,洛谷,NOIP2012,int,res,vector,P1080,return,size
From: https://blog.csdn.net/wang__1233/article/details/140824096