zoukankan      html  css  js  c++  java
  • 洛谷1800 software

    1. 题意:某公司要开发两个软件,每个有m个模块,有n个技术人员,每个人开发不同软件的时间不同。
    2. 思路:属于求最大值最小问题,求两个任务完成的最大天数的最小值。而且答案是单调的,于是想到了二分答案,就得到了天数,所以需要判断能否行得通,这时就想到了DP(类完全背包)。用软件1做m个时 当前天数是否满足做m个软件2为判断依据。
    3. 方程含义:f[i][j]表示前i个人做j个软件1的模块时最多能做几个软件二的模块。

    4. 方程 :f[i][j]=max{f[i][j],f[i-1][k]+res/b[i]}//详见代码注释

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <cstdlib>
    using namespace std;
    const int N=110;
    int n,m,a[N],b[N],l,r,mid,ans;
    int f[N][N];
    
     bool dp(int num)
    {
    	memset(f,0,sizeof(f));
    	f[0][0]=1;//初始化
    	int i,j,k,res;
    	for (i=1; i<=n; i++)
    		for (j=0; j<=m; j++)
    			for (k=j; k>=0; k--)//i-1个人做k个软件1模块,第i个人做j-k个
    			{
    				res=num-a[i]*(j-k);
    				if (res<0) break;//判断第i个人能否做
    				if (f[i-1][k]>0) f[i][j]=max(f[i][j],f[i-1][k]+res/b[i]);
    			}
    	
    	if (f[n][m]>m) return true;
    	return false;
    }
     int main()
    {
    	int tmp=0;
    	scanf("%d%d",&n,&m);
    	for (int i=1; i<=n; i++) 
    	{
    		scanf("%d%d",&a[i],&b[i]);
    		if (a[i]+b[i]>tmp) tmp=a[i]+b[i];
    	}
    	r=tmp*m; l=1;
    	while (l<=r)
    	{
    		mid=(l+r)/2;
    		if (dp(mid)) {ans=mid; r=mid-1;}
    		else l=mid+1;
    	}//熟悉的二分
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    投票通过,PHP 8 确认引入 Union Types 2.0
    Laravel 菜鸟的晋级之路
    给公司写的composer包开发的规范
    Swoft 源码剖析
    听说PHP的生成器yield处理大量数据杠杠的
    读懂JWT的使用,你就会用PHP如何实现了
    python标准库及其它应用
    python常用算法题
    python迭代器实例
    python生成器实例
  • 原文地址:https://www.cnblogs.com/lyxzhz/p/12388569.html
Copyright © 2011-2022 走看看