zoukankan      html  css  js  c++  java
  • TYVJ P2072

    背景 Background

    NOIP 2012 提高组 题2

    描述 Description

    恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然 后,让这 n 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的 所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。
    国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

    输入格式 InputFormat

    第一行包含一个整数 n,表示大臣的人数。
    第二行包含两个整数 a 和 b,之间用一个空格隔开,分别表示国王左手和右手上的整数。
    接下来 n 行,每行包含两个整数 a 和 b,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。

    输出格式 OutputFormat

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

    样例输入 SampleInput [复制数据]

    3
    1 1
    2 3
    7 4
    4 6

    样例输出 SampleOutput [复制数据]

    2

    数据范围和注释 Hint

    【输入输出样例说明】
    按 1、2、3 号大臣这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;
    按 1、3、2 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;
    按 2、1、3 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;
    按 2、3、1 这样排列队伍,获得奖赏最多的大臣所获得金币数为 9;
    按 3、1、2 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;
    按 3、2、1 这样排列队伍,获得奖赏最多的大臣所获得金币数为 9。
    因此,奖赏最多的大臣最少获得 2 个金币,答案输出 2。
    【数据范围】
    对于 20%的数据,有 1≤ n≤ 10,0 < a、b < 8;
    对于 40%的数据,有 1≤ n≤20,0 < a、b < 8;
    对于 60%的数据,有 1≤ n≤100;
    对于 60%的数据,保证答案不超过 109;
    对于 100%的数据,有 1 ≤ n ≤1,000,0 < a、b < 10000。
     
    思路:当时比赛时我只有50分。当然没想到正解,好像是N^3的伪DP
    现在知道了该怎么做了。。讲讲为什么要按照a*b排序
    我们假设一个方案
    a b
    c d
    e f
    g h
    第三项的值:a*c/f
    第四项的值:a*c*e/h
    假设我们交换第三项和第四项
    变成
    a b
    c d
    g h
    e f
    第三项的值:a*c/h
    第四项的值:a*c*g/f
    如果我们交换能获得更优的值,那么我们需要做比较。。第一次的第四项的值显然>第二次第三项的值
    那么主要是比较第一次第四项的值和第二次第四项的值
    需要满足:a*c*e/h>a*c*g/f 整理一下 e*f>h*g
    那么也就是说:如果前一项的两个数的乘积>后一项的两个数的乘积,那么总能交换它们得到更优的值,故应该按照乘积大小排序
    注意要高精!!!压8位的话,数组开到600就够了
     
    #include <cmath>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <cstdlib>
    using namespace std;
    
    typedef long long ll;
    const int maxn=2210,ml=10200,maxl=600;
    const ll mod=100000000;
    struct qq
    {
    	int a,b;
    	friend bool operator < (qq a,qq b)
    	{
    		return a.a*a.b<b.a*b.b;
    	}
    } q[maxn];
    ll c[ml],d[ml],add,ans[ml],t;
    int vv,n;
    
    
    void close()
    {
    exit(0);
    }
    
    bool judge()
    {
    	for (int i=1;i<=maxl;i++)
    		if (d[i]>ans[i])
    			return true;
    		else
    			if (ans[i]>d[i])
    				return false;
    	return true;
    }
    
    void compare()
    {
    	if (judge())
    		memcpy(ans,d,sizeof(d));
    }
    
    void mul(ll *a,int v)
    {
    	add=0;
    	for (int i=maxl;i>=1;i--)
    	{
    		t=a[i]*v+add;
    		a[i]=t % mod;
    		add=t / mod;
    	}
    }
    
    void divide(ll *a,int div)
    {
    	add=0;
    	for (int i=1;i<=maxl;i++)
    	{
    		t=add*mod+a[i];
    		a[i]=t / div;
    		add=t % div;
    	}
    }
    		
    void print(ll *a)
    {
    	int i;
    	for (i=1;i<maxl && a[i]==0;i++);
    	printf("%lld",a[i]);
    
    	if (i==maxl) printf("
    ");
    	for (int j=i+1;j<=maxl;j++)
    	{
    		printf("%08lld",a[j]);
    		if (j==maxl)
    			printf("
    ");
    	}
    }
    
    void work()
    {
    	ans[maxl]=vv / q[1].b;
    	c[maxl]=vv;
    	for (int i=1;i<n;i++)
    	{
    		mul(c,q[i].a);
    		memcpy(d,c,sizeof(c));
    		divide(d,q[i+1].b);
    		/*
    		printf("c:");
    		printf("d:");
    		printf("--------------------
    ");
    		
    		print(c);
    		print(d);
            */
    		compare();
    	}
    	print(ans);
    }
    
    void init()
    {
    	scanf("%d",&n);
    	int useless;
    	scanf("%d %d",&vv,&useless);
    	for (int i=1;i<=n;i++)
    		scanf("%d %d",&q[i].a,&q[i].b);
    	sort(q+1,q+n+1);
    	ans[maxl]=vv;
    	work();
    }
    
    int main ()
    {
    	init();
    	close();
    	return 0;
    }
    
     
  • 相关阅读:
    hdu 1455 N个短木棒 拼成长度相等的几根长木棒 (DFS)
    hdu 1181 以b开头m结尾的咒语 (DFS)
    hdu 1258 从n个数中找和为t的组合 (DFS)
    hdu 4707 仓鼠 记录深度 (BFS)
    LightOJ 1140 How Many Zeroes? (数位DP)
    HDU 3709 Balanced Number (数位DP)
    HDU 3652 B-number (数位DP)
    HDU 5900 QSC and Master (区间DP)
    HDU 5901 Count primes (模板题)
    CodeForces 712C Memory and De-Evolution (贪心+暴力)
  • 原文地址:https://www.cnblogs.com/cssystem/p/3170670.html
Copyright © 2011-2022 走看看