• 机器分配——线性dp输出路径


    题目描述

    总公司拥有高效设备M台, 准备分给下属的N个分公司。各分公司若获得这些设备,可以为国家提供一定的盈利。问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值。其中M <= 15,N <= 10。分配原则:每个公司有权获得任意数目的设备,但总台数不超过设备数M。

    输入格式
    第1行有两个数,第一个数是分公司数N,第二个数是设备台数M。接下来是一个N*M的矩阵,表明了第i个公司分配j台机器的盈利。
    
    输出格式
    第1行输出最大盈利值。
    接下来N行,每行2个数,即分公司编号和该分公司获得设备台数。
    

    样例

    样例输入

    3 3
    30 40 50
    20 30 50
    20 25 30
    

    样例输出

    70
    1 1
    2 1
    3 1
    

    思路分析

    这题关键点有两个:

    • 将机器进行分组分配并记录
    • 输出路径
      主要说一下输出路径这里,首先可以确定,在状态转移的时候每个更优的状态都是用某个公司分配k个机器更新的,联想到背包问题,就是容量为j的背包在装入了k件第i件物品所获得的最优值,最后一次被更新时存储的就是我们要的答案

    代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int maxn = 20;
    int dp[maxn][maxn],a[maxn][maxn],path[maxn][maxn];
    void Print(int x,int y){ //递归输出,x代表前x个公司,y代表待分配的机器数
    	if(x == 0)return;
    	Print(x-1,y-path[x][y]); //返回上一级路径
    	printf("%d %d
    ",x,path[x][y]); 
    }
    int main(){
    	int n,m;scanf("%d%d",&n,&m);
    	for(int i = 1;i <= n;i++){
    		for(int j = 1;j <= m;j++){
    			scanf("%d",&a[i][j]);
    		}
    	}
    	for(int i = 1;i <= n;i++){ //i为公司
    		for(int j = 1;j <= m;j++){ //j为所有公司分配的机器数
    			for(int k =0;k <= j;k++){ //k为该公司分配的机器个数
    				int val = dp[i-1][j-k] + a[i][k];
    				if(dp[i][j] <= val){ //更新dp并记录所分配的公司
    					dp[i][j] = val;
    					path[i][j] = k; //path记录该公司所分配的个数
    				}
    			}
    		}
    	}	
    	printf("%d
    ",dp[n][m]);
    	Print(n,m);
    	return 0;
    }
    
    
    
  • 相关阅读:
    1.3 Starting a New Job 1.3.3 Background Reading(I)
    1.3 Starting a New Job 1.3.1 Preparation
    1.2 Interview 1.2.4 Sample Test(IV)
    1.2 Interview 1.2.4 Sample Test(III)
    Jquery获取元素集合并遍历
    Oracle21c RAC+DG生产项目实战(RHEL8+Oracle集群+容灾+CDB/PDB)
    Django
    Linux 实用命令
    Python人工智能:原理、实践及应用-资料分享
    关于HDFS的NameNode和SecondaryNameNode的一些疑问解答
  • 原文地址:https://www.cnblogs.com/hhhhalo/p/13132461.html
Copyright © 2020-2023  润新知