为第i个工程计算最优时,只需将分配若干给前i-1个工程、剩下的留给当前工程得到的各种分配方案,和只分配给当前工程的方案,取其中的最大值即可;而第一个工程解就是只分配给自身的解。
- #include<iostream>
- using namespace std;
- #define M 10 // 最多资源份量
- #define N 10 // 最多工程数量
- int g[M+1][N]; // 资源分配利润函数
- int solve[N]; // 最优分配方案
- int m, n; // 资源数与工程数
- int dp(){
- int f[M+1][N]; // 资源分配最多利润
- int d[M+1][N]; // 资源分配方案
- int best; // 资源分配最优方案可得利润best,
- int bi, bj; // 最优时资源分配给了前bi个项目,共分配bj份资源
- int i,j,k;
- // 先得到只有第一个工程时的利润
- for(i=0; i<=m; i++){
- f[0][i] = g[0][i];
- d[0][i] = i;
- }
- // 计算n个工程的资源分配表
- for(i=1; i<n; i++){
- f[i][0] = g[i][0] + f[i-1][0], d[i][0] = 0; // 当为0时解直接相加
- for(j=1; j<=m; j++){
- f[i][j] = f[i][0], d[i][j] = 0; // 初始化为不分配给该工程资源时的解
- for(k=0; k<=j; k++){ // 计算分配给其若干个资源时的最优解
- if(f[i-1][j-k] + g[i][k] > f[i][j]){
- f[i][j] = f[i-1][j-k] + g[i][k];
- d[i][j] = k;
- }
- }
- }
- }
- // 寻找最优分配方案
- for(i=0; i<n; i++){
- for(j=0; j<=m; j++){
- if(f[i][j]>best){
- best = f[i][j];
- bi = i, bj = j;
- }
- }
- }
- // 计算每个工程各消耗多少资源
- memset(solve, 0, sizeof(solve));
- k = bj;
- for(i=bi; i>=0; i--){ // bi以后的项目都不用分配
- solve[i] = d[i][k];
- k-=solve[i];
- }
- return best;
- }
- int main(){
- int i,j;
- cin>>m>>n;
- for(i=0; i<n; i++){
- for(j=0; j<=m; j++){
- cin>>g[i][j];
- }
- }
- cout<<"最优分配方案可得利润:"<<dp()<<endl;
- cout<<"最优分配方案:"<<endl;
- for(i=0; i<n; i++){
- cout<<"工程"<<(i+1)<<"分配:"<<solve[i]<<"资源"<<endl;
- }
- return 0;
- }