P1080 国王游戏 贪心 高精度

  

题目描述

恰逢 HH国国庆,国王邀请nn 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 nn 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。

国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

输入输出格式

输入格式:

第一行包含一个整数nn,表示大臣的人数。

第二行包含两个整数 aa和 bb,之间用一个空格隔开,分别表示国王左手和右手上的整数。

接下来 nn行,每行包含两个整数aa 和 bb,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。

输出格式:

一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。

输入输出样例

输入样例#1: 复制
3 
1 1 
2 3 
7 4 
4 6 
输出样例#1: 复制
2

说明

【输入输出样例说明】

11、22、33 这样排列队伍,获得奖赏最多的大臣所获得金币数为 22;

按 11、33、22 这样排列队伍,获得奖赏最多的大臣所获得金币数为22;

按 22、11、33 这样排列队伍,获得奖赏最多的大臣所获得金币数为 22;

22、33、11这样排列队伍,获得奖赏最多的大臣所获得金币数为99;

按 33、11、22这样排列队伍,获得奖赏最多的大臣所获得金币数为 22;

33、22、11 这样排列队伍,获得奖赏最多的大臣所获得金币数为 99。

因此,奖赏最多的大臣最少获得 22个金币,答案输出 22。

【数据范围】

对于 20%的数据,有 1≤ n≤ 10,0 < a,b < 81n10,0<a,b<8;

对于 40%的数据,有1≤ n≤20,0 < a,b < 81n20,0<a,b<8;

对于 60%的数据,有 1≤ n≤1001n100;

对于 60%的数据,保证答案不超过 10^9109;

对于 100%的数据,有 1 ≤ n ≤1,000,0 < a,b < 100001n1,000,0<a,b<10000。

NOIP 2012 提高组 第一天 第二题

右边的数是除数  按照右边为第一优先级  左边为第二优先级  都降序排序   比较符合贪心原则  但是只能过6个点

#include<bits/stdc++.h>
using namespace std;
//input
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);i--)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m);
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define inf 0x3f3f3f3f
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define N 1000+5
struct node
{
    int l,r;
}s[N];
bool cmp(node a,node b)
{
    return a.l<b.l||a.l==b.l&&a.r<b.r;
}
bool cmp2(node a,node b)
{
    return a.r<b.r||a.r==b.r&&a.l<b.l;
}
int main()
{
    int n;
    int L,R;
    RIII(n,L,R);
    rep(i,1,n)
    RII(s[i].l,s[i].r);

    sort(s+1,s+1+n,cmp2);
    ll maxx2=-99000999999;
    ll sum=L;
    rep(i,1,n)
    {
        maxx2=max(maxx2,sum/s[i].r);
        sum*=s[i].l;
    }
    cout<<maxx2;

    return 0;
}
View Code

剩下的点为高精度 

事实证明上面的贪心原则是错误的  只是我想当然而已

参考了大佬的题解:

 

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;

int n, lens = 1, lenm = 1, lena = 1;
int sum[10010] = {0, 1}, maxn[10010] = {0, 1}, ans[10010];

struct tmp
{
    long long l, r;
    bool operator < (const tmp x) const 
    {
            return l * r < x.l * x.r;
    }
}coin[1001];

void muti(long long x)
{
    int tmp = 0;
    for(int i = 1; i <= lens; i++)
        sum[i] *= x;
    for(int i = 1; i <= lens; i++)
    {
        tmp += sum[i];
        sum[i] = tmp %10;
        tmp /= 10;
    }
    while(tmp != 0)
    {
        lens++;
        sum[lens] = tmp % 10;
        tmp /= 10;
    }
}

void cut(long long x)
{
    memset(ans, 0, sizeof(ans));
    lena = lens;
    int tmp = 0;
    for(int i = lena; i >= 1; i--)
    {
        tmp *= 10;
        tmp += sum[i];
        if(tmp >= x)
        {
            ans[i] = tmp / x;
            tmp %= x;
        }
    }
    while(ans[lena] == 0)
    {
        if(lena == 1)
            break;
        lena--;
    }
}

void max()
{
    if(lena > lenm)
    {
        for(int i = 1; i <= lena; i++)
            maxn[i] = ans[i];
        lenm = lena;
    }
    else if(lena == lenm)
    {
        for(int i = lena; i >= 1; i--)
            if(maxn[i] < ans[i])
            {
                for(int j = 1; j <= lena; j++)
                    maxn[j] = ans[j];
                lenm = lena;
                break;
            }
    }
}

int main()
{
//  freopen("game.in", "r", stdin);
//  freopen("game.out", "w", stdout);
    cin >> n;
    cin >> coin[0].l >> coin[0].r;
    for(int i = 1; i <= n; i++)
        scanf("%d %d", &coin[i].l, & coin[i].r);
    sort(coin + 1, coin + n + 1);
    for(int i = 1; i <= n; i++)
    {
        muti(coin[i - 1].l);
        cut(coin[i].r);
        max();
    }
    for(int i = lenm; i >= 1; i--)
        cout << maxn[i];
}
View Code
原文地址:https://www.cnblogs.com/bxd123/p/10661842.html