背包问题学习链接:
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