LightOJ 1180 Software Company(区间)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1180

题意:n个工人,两份任务A和B,每份任务被分成m份,不放A的一份为a,B的一份为b。给出每个人做a和b的时间。求干完A和B的最小时间。

思路:f[i][j]表示前i个人干A的j份最多可以干B多少分,二分答案。。。。好犀利啊。。

View Code
 1 #include <iostream>

 2 #include <cstdio>

 3 #include <cstring>

 4 #define max(x,y) ((x)>(y)?(x):(y))

 5 using namespace std;

 6 

 7 int C,num=0;

 8 int a[105],b[105],dp[105],n,m;

 9 

10 int OK(int mid)

11 {

12     int i,j,k,t;

13     memset(dp,-1,sizeof(dp));

14     dp[0]=0;

15     for(i=1;i<=n;i++)

16     {

17         t=mid/a[i];

18         for(j=m;j>=0;j--) for(k=0;k<=t&&k<=j;k++) if(dp[j-k]!=-1)

19             dp[j]=max(dp[j],dp[j-k]+(mid-k*a[i])/b[i]);

20         if(dp[m]>=m) break;

21     }

22     return dp[m]>=m;

23 }

24 

25 int main()

26 {

27     for(scanf("%d",&C);C--;)

28     {

29         scanf("%d%d",&n,&m);

30         int i;

31         for(i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);

32         int low=1;

33         int high=a[1]*m+b[1]*m;

34         int mid;

35         while(low<=high)

36         {

37             mid=(low+high)>>1;

38             if(OK(mid)) high=mid-1;

39             else low=mid+1;

40         }

41         printf("Case %d: ",++num);

42         if(high>=1&&OK(high)) printf("%d\n",high);

43         else printf("%d\n",low);

44     }

45     return 0;

46 }

 

 

你可能感兴趣的:(software)