2017.2.11【初中部 GDKOI】模拟赛B组 T2:软件公司

**【NOIP2013模拟11.6B组】软件公司(company) **
Description

一家软件开发公司有两个项目,并且这两个项目都由相同数量的m个子项目组成,对于同一个项目,每个子项目都是相互独立且工作量相当的,并且一个项目必须在m个子项目全部完成后才算整个项目完成。

这家公司有n名程序员分配给这两个项目,每个子项目必须由一名程序员一次完成,多名程序员可以同时做同一个项目中的不同子项目。

求最小的时间T使得公司能在T时间内完成两个项目。

Input

第一行两个正整数n,m(1<=n<=100,1<=m<=100)。

接下来n行,每行包含两个整数,x和y。分别表示每个程序员完成第一个项目的子程序的时间,和完成第二个项目子程序的时间。每个子程序耗时也不超过100。

Output

输出最小的时间T。

Sample Input

3 20

1 1

2 4

1 6

Sample Output

18

【样例解释】

第一个人做18个2项目,耗时18;第二个人做2个1项目,2个2项目耗时12;第三个人做18个1项目,耗时18。

题解:本题还是挺简单的,但是要灵活去想动态规划和二分查找,还要灵活应用。当然,被你发现了,本题正解就是二分查找用动态规划优化。(好像很深奥)但是,60%和30%也很值得一提!

30%:可以用一个二分查找来查找答案,然后再判断一下成不成立就30分到手啦!!

60%:当然是用DP啦。这个dp我是用一种神奇的方法,f[i,x,y]表示,第i个人,第一批项目已完成x个子项目,第二批项目已完成y个子项目的最短时间。dp方程自己想想,当然,也有第二种方法(不一定是60分,但数据这么水,我也无法确定)。第二种方法:f[i,j]表示,当选到第i个人,第一批货物已完成j个子项目,还可以做多少个二项目。这种方法更简单,当然更快,100分就用到了这种方法。

方法1伪代码:

 for i:=1 to n do
        begin
                for a:=0 to m do
                begin
                        for b:=0 to m do
                        begin
                                for o:=0 to a do
                                begin
                                        for p:=0 to b do
                                        begin
                                                f[i,a,b]:=min(f[i,a,b],max(f[i-1,a-o,b-p],o*x[i]+p*y[i]));
                                        end;
                                end;
                        end;
                end;
        end;

100%:在二分里面的判断过程,用dp来做就非常快啦,然后100分就到手啦~~~

标程:

var
        i,j,k,l,n,m,a,b,o,p:longint;
        f:array[0..100,0..100,0..100] of longint;
        x,y:array[1..100] of longint;
function max(x,y:longint):longint;
begin if x>y then exit(x); exit(y); end;
function min(x,y:longint):longint;
begin if x<y then exit(x); exit(y); end;
begin
        assign(input,'company.in');reset(input);
        assign(output,'company.out');rewrite(output);
        readln(n,m);
        for i:=1 to n do
        begin
                readln(x[i],y[i]);
        end;
        fillchar(f,sizeof(f),127);
        f[0,0,0]:=0;
        qs(1,n);
        for i:=1 to n do
        begin
                for a:=0 to m do
                begin
                        for b:=0 to m do
                        begin
                                for o:=0 to a do
                                begin
                                        for p:=0 to b do
                                        begin
                                                f[i,a,b]:=min(f[i,a,b],max(f[i-1,a-o,b-p],o*x[i]+p*y[i]));
                                        end;
                                end;
                        end;
                end;
        end;
        writeln(f[n,m,m]);
end.


动态规划还是要会呀,当然,也要放开算法的拘束,搞搞别的东东,说不定就是正解了!!!

posted @ 2017-02-11 21:04  RainbowCrown  阅读(146)  评论(0编辑  收藏  举报