zoukankan      html  css  js  c++  java
  • DP大乱炖 A

    There are two kinds of tasks, namely A and B. There are N workers and the i-th worker would like to finish one task A in ai minutes, one task B in bi minutes. Now you have X task A and Y task B, you want to assign each worker some tasks and finish all the tasks as soon as possible. You should note that the workers are working simultaneously.

    input:In the first line there is an integer T(T<=50), indicates the number of test cases. 
    In each case, the first line contains three integers N(1<=N<=50), X,Y(1<=X,Y<=200). Then there are N lines, each line contain two integers ai, bi (1<=ai, bi <=1000). 

    output:For each test case, output “Case d: “ at first line where d is the case number counted from one, then output the shortest time to finish all the tasks.

     Sample input:

    3
    2 2 2
    1 10
    10 1
    2 2 2
    1 1
    10 10
    
    3 3 3
    2 7
    5 5
    7 2

     Sample output:

    Case 1: 2
    Case 2: 4
    Case 3: 6
    题目链接:
    http://acm.hdu.edu.cn/showproblem.php?pid=3433
    题目分析:
    你要明白最多所需花费时间为所有人中花费时间最多的人的时间,对于这个时间,我们可以二分得到,然后用DP来验证。
    详细DP验证过程,请看代码注释
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iomanip>
    #include<algorithm>
    using namespace std;
    int t;
    int n,m,f[55][510],a[51],b[51],x,y,l,r;
    bool work(int p)
    {
        memset(f,-1,sizeof(f));
        //每次验证之前需要把数组全部赋值为负 
        f[0][0]=0;
        for(int i=1;i<=n;i++)//枚举每一个工人 
        {
            for(int j=0;j<=x;j++)//在此处,我们做一个类似于背包问题的dp,把所需要做A时间看为背包代价 
            {
                f[i][j]=f[i-1][j];
                for(int k=0;k<=j;k++)//在做j个A事件时能做的最多的B事件 
                {
                    if(p-k*a[i]<0) break;
                    if(f[i-1][j-k]!=-1)
                    f[i][j]=max(f[i][j],f[i-1][j-k]+(p-k*a[i])/b[i]);
                }
            }
        }
        if(f[n][x]>=y) return true;//如果在做完所有A事件的时候所能做最多数量的B事件。 
        else return false;
    }
    int main()
    {
        scanf("%d",&t);
        for(int qw=1;qw<=t;qw++)
        {
            scanf("%d%d%d",&n,&x,&y);
            for(int i=1;i<=n;i++){scanf("%d%d",&a[i],&b[i]);}
            l=1,r=1000000;
            while(l+1<r)//二分枚举最短时间 
            {
                int mid=(l+r)/2;
                if(work(mid))r=mid;
                else l=mid;
            }
            cout<<"Case "<<qw<<": ";
            if(work(l))cout<<l<<endl;
            else cout<<r<<endl;
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    PHP -----上传文件
    PHP----预定义数组
    PHP-------- 会话控制
    PHP------XML
    PHP----练习-----三级联动
    PHP-------ajax返回值 返回JSON 数据
    PHP----练习----光标离开文本框时变色
    使用ansible安装配置zabbix客户端
    svn+apache安装配置
    rsync+lsyncd实现实时同步
  • 原文地址:https://www.cnblogs.com/mybing/p/7358364.html
Copyright © 2011-2022 走看看