zoukankan      html  css  js  c++  java
  • 贪心+huffman编码+模拟退火+分治(一)

    (一)贪心

    1.A - 今年暑假不AC

    “今年暑假不AC?” 
    “是的。” 
    “那你干什么呢?” 
    “看世界杯呀,笨蛋!” 
    “@#$%^&*%...” 

    确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了。 
    作为球迷,一定想看尽量多的完整的比赛,当然,作为新时代的好青年,你一定还会看一些其它的节目,比如新闻联播(永远不要忘记关心国家大事)、非常6+7、超级女生,以及王小丫的《开心辞典》等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目) 

    Input输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。 
    Output对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。Sample Input

    12
    1 3
    3 4
    0 7
    3 8
    15 19
    15 20
    10 15
    8 18
    6 12
    5 10
    4 14
    2 9
    0

    Sample Output

    5
    解题思路:贪心思路:将每个数据用pair储存起来,根据结束时间进行从小到大排序,在循环模拟时,若果下一个的起始时间<上一个的结束时间,
    则可以++,并将该结束时间作为下回判断的结束时间;否则循环下一个。
    代码:
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define x first
    #define y second
    using namespace std;
    const int N=110;
    typedef  pair<int,int> PII;
    int t;
    PII f[N];
    int main()
    {
        int s,e,i,j,n;
        while(scanf("%d",&n)&&n)
        {
            for(i=0;i<n;i++)
            {
                scanf("%d%d",&s,&e);
                f[i].x=e,f[i].y=s;
            }
            sort(f,f+n);
            int ans=1;
            int tem=f[0].x;
            for(i=1;i<n;i++)
            {
                if(f[i].y>=tem)
                {
                    ans++;
                    tem=f[i].x;
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }

    2.B - 迷瘴

    通过悬崖的yifenfei,又面临着幽谷的考验—— 
    幽谷周围瘴气弥漫,静的可怕,隐约可见地上堆满了骷髅。由于此处长年不见天日,导致空气中布满了毒素,一旦吸入体内,便会全身溃烂而死。 
    幸好yifenfei早有防备,提前备好了解药材料(各种浓度的万能药水)。现在只需按照配置成不同比例的浓度。 
    现已知yifenfei随身携带有n种浓度的万能药水,体积V都相同,浓度则分别为Pi%。并且知道,针对当时幽谷的瘴气情况,只需选择部分或者全部的万能药水,然后配置出浓度不大于 W%的药水即可解毒。 
    现在的问题是:如何配置此药,能得到最大体积的当前可用的解药呢? 
    特别说明:由于幽谷内设备的限制,只允许把一种已有的药全部混入另一种之中(即:不能出现对一种药只取它的一部分这样的操作)。 
     

    Input输入数据的第一行是一个整数C,表示测试数据的组数; 
    每组测试数据包含2行,首先一行给出三个正整数n,V,W(1<=n,V,W<=100); 
    接着一行是n个整数,表示n种药水的浓度Pi%(1<=Pi<=100)。 
    Output对于每组测试数据,请输出一个整数和一个浮点数; 
    其中整数表示解药的最大体积,浮点数表示解药的浓度(四舍五入保留2位小数); 
    如果不能配出满足要求的的解药,则请输出0 0.00。 
    Sample Input

    3
    1 100 10
    100
    2 100 24
    20 30
    3 100 24
    20 20 30

    Sample Output

    0 0.00
    100 0.20
    300 0.23
    解题思路:贪心思路就是优先选择浓度低的,对所有解药进行sort排序,再结合前缀和,从后往前进行遍历,找到第一个浓度小于等于目标浓度的体积时
    结束,输出;特别注意:double x=((s[i]*1.0/100)*v)/((i+1)*v);
    代码:
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int c,n,v;
    int f[110],s[110];
    int w;
    int main()
    {
        int i,j;
        cin>>c;
        while(c--)
        {
            cin>>n>>v>>w;
            for(i=0;i<n;i++)
                cin>>f[i];
            double dow=w/100.00;
            sort(f,f+n);
            s[0]=f[0];
            for(i=1;i<n;i++)
            {
                s[i]=s[i-1]+f[i];
            }
            bool flag=false;
            for(i=n-1;i>=0;i--)
            {
                double x=((s[i]*1.0/100)*v)/((i+1)*v);
                if(x<dow||fabs(x-dow)<1e-8)
                {
                    flag=true;
                    cout<<(i+1)*v<<" ";
                    printf("%.2f
    ",x);
                    break;
                }
            }
            if(flag==false)
                cout<<"0 0.00"<<endl;
        }
        return 0;
    }
    
    

    (二)模拟退火

    1.Strange fuction

    Now, here is a fuction: 
      F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100) 
    Can you find the minimum value when x is between 0 and 100.

    Input

    The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. Then T lines follow, each line has only one real numbers Y.(0 < Y <1e10)

    Output

    Just the minimum value (accurate up to 4 decimal places),when x is between 0 and 100.Sample Input

    2
    100
    200

    Sample Output

    -74.4291
    -178.8534
    解题思路:该题可用二分的思想来解决。
    代码:
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    double find(double x,double y)
    {
        return 6*pow(x,7)+8*pow(x,6)+7*pow(x,3)+5*pow(x,2)-y*x;
    }
    
    double check(double y)
    {
        double l=0,r=100;
        while(r-l>1e-8)
        {
            double mid=(l+r)/2;
            double rmid=(mid+r)/2;
            if(find(mid,y)<find(rmid,y))
                r=rmid;
            else
                l=mid;
        }
        return l;
    }
    
    int main()
    {
        int t,i;
        double y;
        cin>>t;
        while(t--)
        {
            cin>>y;
            double key=check(y);
            printf("%.4f
    ",find(key,y));
        }
        return 0;
    }
    
    
    


  • 相关阅读:
    在MathType如何让括号随内容自动调整大小的技巧
    对于MathType中公式与文字错位的问题怎么解决
    怎样批量修改MathType公式格式
    你与论文达人只差一个MathType的距离
    公式达人必杀技,你会几招?
    如何用MathType快速输入公式
    openfire数据库mysql配置
    thinkphp 操作mssql2008
    phpstudy+php5.2+mssql2008
    thinkphp openfire 添加用户 骨架
  • 原文地址:https://www.cnblogs.com/xiaofengzai/p/12255249.html
Copyright © 2011-2022 走看看