背包问题扩展

背包问题学习链接:

http://blog.csdn.net/kangroger/article/details/38864689

背包九讲

http://blog.csdn.net/sky_fighting/article/details/8789067

背包问题可以理解为动态规划的问题,也可以利用贪心算法完成,但是建议使用动态规划的思路。

关于什么是动态规划,我们可以先看一下这篇文章的讲解,比较通俗易懂

http://www.cnblogs.com/sdjl/articles/1274312.html

代码:

#include <stdio.h>
#include <string.h>
int invest[301][21];
int total_invest;
int company_num;
int max[301];

int main(void)
{
    int tc, T;
    
    freopen("input.txt", "r", stdin);

    setbuf(stdout, NULL);

    scanf("%d", &T);
    for(tc = 0; tc < T; tc++)
    {
        total_invest = 0;
        company_num = 0;

        memset(max, 0, sizeof(max));

        scanf("%d %d",&total_invest,&company_num);
        
        int i,j,k;

        for(i=1;i<=total_invest;i++)
        {
            for(j=0;j<=company_num;j++)
            {
                scanf("%d",&invest[i][j]);
            }
        }
        
        /* 当有j个公司参与投资的时候*/
        for(j=1;j<=company_num;j++)
        {    
            /*分别求每个投资金额对应的最大收益,投资金额从大到小,是因为这样可以避免一个公司重复投两个金额*/
            for(i=total_invest;i>=1;i--)
            //for(i=1;i<=total_invest;i++)
            {
                int tmp = -1;
                /*如果j公司投资金额为k,则i-k(剩余投资金额的最大额)+当前j公司的投资金额是否大于先前的max[i-k],如果大于则覆盖,否则跳过*/
                for(k=1;k<=i;k++)
                {
                    if(invest[k][j] + max[i-k] > max[i])
                    {
                        max[i] = invest[k][j] + max[i-k];
                    }
                }
            }

        }
        
        printf("%d
",max[total_invest]);        

    }

    return 0;//Your program should return 0 on normal termination.
}

测试数据:

5
4 2
1 3 3
2 4 4
3 7 6
4 8 8
7 2
1 3 3
2 4 4
3 7 6
4 8 8
5 10 10
6 13 13
7 15 15
5 3
1 4 4 3
2 6 7 6
3 8 8 9
4 13 13 13
5 15 14 15
10 3
1 4 4 3
2 6 7 6
3 8 8 9
4 13 13 13
5 15 14 15
6 19 18 19
7 20 20 20
8 23 25 23
9 27 27 26
10 31 31 31
5 5
1 3 4 6 2 6
2 11 10 10 9 11
3 12 12 13 14 13
4 18 17 19 19 18
5 23 26 24 25 24

测试结果:

10
16
17
33
28
原文地址:https://www.cnblogs.com/monkeyvera/p/4335731.html