NOIP2012 国王游戏(贪心)

原题链接

题目描述

在这里插入图片描述

输入描述

在这里插入图片描述

输出描述

在这里插入图片描述

输入样例

3 
1 1 
2 3 
7 4 
4 6 

输出样例

2

样例说明

在这里插入图片描述

数据范围

在这里插入图片描述


本题中不难发现,交换任意两个大臣时,只会影响他们各自的金币数,而不会影响他们之前和之后的大臣的金币数,因此可以考虑贪心对比两个大臣交换前后的金币。假设相邻的两个大臣中,其左右手分别为 a1,b1,a2,b2,之前所有人的左手乘积总和为 sum,可得交换前为 sum * a1 / b2,交换后为 sum * a2 / b1,若存在交换前 > 交换后,可推出 a1 * b1 > a2 * b2,此时交换两大臣可使获得金币减少。即对大臣左右手金币的乘积进行上升排列即是最优方法。

本题坑点是,需要使用高精度!!

参考代码

#include <bits/stdc++.h>
using namespace std;

struct a{
	int l,r;
}a[1010];
int k[1010];
int f[1010],fs[1010];
int main(){
	int n;
	cin>>n;
	int m;
	for(int i=0;i<=n;i++){
		cin>>a[i].l>>a[i].r;
		k[i]=a[i].l*a[i].r;
	}
	
	for(int i=1;i<n;i++)
    	for(int j=1;j<=n-i;j++)
    		if(k[j]>k[j+1]){ 
    			swap(a[j].l,a[j+1].l);
    			swap(a[j].r,a[j+1].r);
    			swap(k[j],k[j+1]);
    		}
    		
	f[0]=a[0].l;
    long double s=0,t=a[0].l;
    int si=0;
    for(int i=1;i<=n;i++){
        if(t/a[i].r>s){
           	s=t/a[i].r;
           	m=0;
        	for(int j=n-1;j>=0;j--){
                m=10000*m+f[j];
                fs[j]=m/a[i].r;
                m%=a[i].r;
                }
            si=i;
        }
        t*=a[i].l; 
        m=0; 
        for(int j=0;j<=n-1;j++){ 
        	m+=f[j]*a[i].l; 
        	f[j]=m%10000; 
        	m/=10000; 
        } 
    }
    m=0;
    for (int j=n-1; j>=0; j--) { 
        if (m==1){ 
        	if(fs[j]<10) cout<<"000"; 
        	else if (fs[j]<100) cout<<"00"; 
    		else if (fs[j]<1000) cout<<"0"; 
            cout<<fs[j]; 
        } 
        else if(fs[j]>0){
			cout<<fs[j];
        	m=1;
        } 
    }
	
	return 0;
} 
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值