C++ 机器分配,NOIP,csp

题目描述
【题目描述】
总公司拥有高效设备MM台,准备分给下属的NN个分公司。各分公司若获得这些设备,可以为国家提供一定的盈利。问:如何分配这MM台设备才能使国家得到的盈利最大?求出最大盈利值。其中M\le 200M≤200,N\le 100N≤100。分配原则:每个公司有权获得任意数目的设备,但总台数不超过设备数MM。
输入格式
第一行有两个数,第一个数是分公司数NN,第二个数是设备台数MM。
接下来是一个N\times MN×M的矩阵,第ii行第jj列表明了第ii个公司分配jj台机器的盈利。 不超过10^410
4

输出格式
第1行为最大盈利值
第2到第n+1n+1行, 每行两个整数,为ii和第ii个公司分到的台数
要求答案的字典序最小

输入样例
输入
3 3
30 40 50
20 30 50
20 25 30
输出样例
输出
70
1 1
2 1
3 1

深度优先搜索吧


#include <bits/stdc++.h>
using namespace std;
int n,m,a[11][20],b[20],jians[20],ans;
void dfs(int zhi,int b[],int qian,int k)
{
 
        if(qian>ans)
        {
            ans=qian;
            for(int i=1;i<=n;i++)
            {
                jians[i]=b[i];
            }
        }
    if(zhi==0)
    return;
    if(k==0)
    return;
    for(int i=m;i>=0;i--)
    {
        if(zhi>=i)
        {
            b[k]=i;
            dfs(zhi-i,b,qian+a[k][i],k-1);
            b[k]=0;
        }
    }
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
        }
    }
    dfs(m,b,0,n);
    cout<<ans<<endl;
    for(int i=1;i<=n;i++){
        cout<<i<<" "<<jians[i]<<endl;
    }
}

#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 20;
int val[maxn][maxn];
int f[maxn][maxn];
void dfs(int mx,int i,int j){
    if(i == 0) return;
    for(int k = 0;k <= j;k++){
        if(f[i-1][k] + val[i][j-k] == mx){
            dfs(f[i-1][k],i-1,k);
            printf("%d %d\n",i,j-k);
            break;
        }
    }
}
void solve(int n,int m){
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= m;j++){
            for(int k = 0;k <= j;k++){
                if(f[i][j] < f[i-1][j-k] + val[i][k]){
                    f[i][j] = f[i-1][j-k]+val[i][k];
                }
            }
        }
    }
    printf("%d\n",f[n][m]);
    dfs(f[n][m],n,m);
}
int main(){
    int n,m;
    //freopen("123.in","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= m;j++){
            scanf("%d",&val[i][j]);
        }
    }
    solve(n,m);
    return 0;
}

img
找到了一个类似你说的search方法,你看看,如果有帮助请点一下采纳,谢谢!

#include<bits/stdc++.h>
using namespace std;
int n,m,a[20][20],pau[20],f[20],ans;//f[i]是答案机器数,pau是当前假设的机器数量
void search(int Nnum,int Nans,int Nm) {//Nnum是现在的公司编号,Nans是现在的盈利,Nm是剩余的机器 
    if(Nm<0) return;
    if(Nnum==n+1) {
        if(Nans>ans) {
            ans=Nans;
            for(int i=1;i<=n;i++) f[i]=pau[i];
        }
        return;
    }
    for(int i=0; i<=m; i++) 
    pau[Nnum]=i,search(Nnum+1,Nans+a[Nnum][i],Nm-i);//i枚举这个公司用多少台机器 
    return;
}
int main() {
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            scanf("%d",&a[i][j]);
    search(1,0,m);
    printf("%d\n",ans);
    for(int i=1; i<=n; i++) printf("%d %d\n",i,f[i]);
    return 0;
}

P2066 机器分配_mb60b4a73fc42be的技术博客_51CTO博客 P2066 机器分配,题目背景无题目描述总公司拥有高效设备M台,准备分给下属的N个分公司。各分公司若获得这些设备,可以为国家提供一定的盈利。问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值。其中M≤15,N≤10。分配原则:每个公司有权获得任意数目的设备,但总台数不超过设备数M。输入输出格式输入格 https://blog.51cto.com/u_15239936/2865573
可以看下这个

背包

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define SIS std::ios::sync_with_stdio(false)
#define space putchar(' ')
#define enter putchar('\n')
#define lson root<<1
#define rson root<<1|1
typedef pair<int,int> PII;
const int mod=100000000;
const int N=2e6+10;
const int M=1e3+10;
const int inf=0x7f7f7f7f;
const int maxx=2e5+7;

int gcd(int a,int b)
{
    return b==0?a:gcd(b,a%b);
}

ll lcm(ll a,ll b)
{
    return a*(b/gcd(a,b));
}

template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-')
            op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op)
        x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0)
        x = -x, putchar('-');
    if(x >= 10)
        write(x / 10);
    putchar('0' + x % 10);
}
ll qsm(int a,int b,int p)
{
    ll res=1%p;
    while(b)
    {
        if(b&1) res=res*a%p;
        a=1ll*a*a%p;
        b>>=1;
    }
    return res;
}
int a[N];
int dp[105][105];
int w[105][105];
int main()
{

    SIS;
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        cin>>w[i][j];
    for(int i=1;i<=n;i++)
     for(int j=0;j<=m;j++)
     {
         dp[i][j]=dp[i-1][j];
         for(int k=0;k<=j;k++)
         {
             dp[i][j]=max(dp[i][j],dp[i-1][j-k]+w[i][k]);
         }
     }
     cout<<dp[n][m]<<endl;
     for(int i=n;i;i--)
     {
         for(int j=0;j<=m;j++)
         {
             if(dp[i][m]==dp[i-1][m-j]+w[i][j])
             {
                 a[i]=j;
                 m-=j;
                 break;
             }
         }
     }
     for(int i=1;i<=n;i++) cout<<i<<' '<<a[i]<<endl;


    return 0;
}



Path+区间DP

#include<bits/stdc++.h>
using namespace std;
int f[11][16],graph[11][16],path[11][16][11],n,m;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
            cin>>graph[i][j];
    }
    memset(f,0,sizeof(f));
    for(int i=1;i<=n;i++)
        for(int j=0;j<=m;j++)    
            for(int k=0;k<=j;k++)
            {
                if (f[i][j]<f[i-1][k]+graph[i][j-k])
                {
                    f[i][j]=f[i-1][k]+graph[i][j-k];
                    for(int h=1;h<i;h++) path[i][j][h]=path[i-1][k][h];
                    path[i][j][i]=j-k;//因为改为了“不给”第i家公司k台机器,所以必须如此调整
                }
            }
    cout<<f[n][m]<<endl;
    for(int i=1;i<=n;i++) cout<<i<<" "<<path[n][m][i]<<endl;
    return 0;
}

DFS

#include<bits/stdc++.h>
using namespace std;
int n,m,a[20][20],pau[20],f[20],ans;//f[i]是答案机器数,pau是当前假设的机器数量
void dfs(int Nnum,int Nans,int Nm) {//Nnum是现在的公司编号,Nans是现在的盈利,Nm是剩余的机器 
    if(Nm<0) return;
    if(Nnum==n+1) {
        if(Nans>ans) {
            ans=Nans;
            for(int i=1;i<=n;i++) f[i]=pau[i];
        }
        return;
    }
    for(int i=0; i<=m; i++) pau[Nnum]=i,dfs(Nnum+1,Nans+a[Nnum][i],Nm-i);//i枚举这个公司用多少台机器 
    return;
}
int main() {
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            scanf("%d",&a[i][j]);
    dfs(1,0,m);
    printf("%d\n",ans);
    for(int i=1; i<=n; i++) printf("%d %d\n",i,f[i]);
    return 0;
}

Pascal

var  m,n:integer;      
i,j,k,max:longint;    
f- ,value:array[0..10,0..15] of  integer;
procedure  show(i,j:longint)//输出各分公司分配情况
var  klongint;
begin 
if  i=0  then  exit; 
for k:=0 to j do   
  if max=f[i-1,k]+value[i,j-k]  then   
    begin   
    max:=f[i-1,k];    
    show(i-1,k);     
    writeln(i,‘ ‘,j-k);    
    exit;     
    end;     
end;
begin
readln(n,m); 
for I:= 1  to  n  do    
   for j:= 1  to  m  do       
      read(value[i,j]);      
for i:= 1  to  n  do
   for j:=1  to  m  do   
      begin              
      max:=0;               
      for k:= 0  to  j  do        
         if f[i-1,k]+value[i,j-k]>max  then  
           max:=f[i-1,k] + value[i,j-k];   
      f[i,j]:=max;     
      end;  
writeln(f[n,m]);   //输出最大盈利值 
show(n,m);    //输出分配情况
end.