P2066 机器分配

来源:互联网 发布:淘宝助理官方下载免费 编辑:程序博客网 时间:2024/06/12 18:09

题目传送

这个题是简单的dp+递归输出。

注意一个问题,是要求字典序最小的,所以在递归时,倒着循环,而且找到一个合适的值就要break,否则就会在后面将前面的值覆盖。

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#include<cstdlib>#define LL long longusing namespace std;LL f[20][20],a[20][20],n,m;int b[20];void work(int x,int last){    if(x==0) return;    for(int i=last;i>=0;i--)    {        if(f[x][last]==f[x-1][last-i]+a[x][i])        {            b[x]=i;            work(x-1,last-i);            break;//一定不要掉下        }    }}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)     for(int j=1;j<=m;j++)       scanf("%lld",&a[i][j]);    for(int i=1;i<=n;i++)      for(int j=0;j<=m;j++)        for(int k=0;k<=j;k++)          f[i][j]=max(f[i][j],f[i-1][k]+a[i][j-k]);    printf("%lld\n",f[n][m]);    work(n,m);    for(int i=1;i<=n;i++) printf("%d %d\n",i,b[i]);    return 0;}