很早前就想写博客记录下自己的学习路程,
就从今天开始写起把。那啥今天周末,大家好多人应该都出去玩了。
当然在寝室dota的也有拉,哈哈。
希望那些以爱好programming的大哥大姐大叔大婶小弟小妹都能坚持下来。
前面的路还很长,要学的也很多。专注你所学的,多思考,多动手,多调试。就一定会有收获。
该程序在gcc和vc下通过。
转载请注明出处,谢谢!
#include <stdio.h>
#include <stdlib.h>
//先排序
//很简单的一种排序,不要bs俺
void sort(int *p, int num)
{
for (int i = 0; i < num - 1; i++){
for (int j = i + 1; j < num; j++){
if (p[i] > p [j]){//利用加法交换
p[i] += p[j];
p[j] = p[i] - p[j];
p[i] -= p[j];
}
}
}
}
//找出最优解
//循环很多,最好自己能在纸上画画,还是就是防止越界
//有时候眼睛看不出来的时候,可以调试下
void bag(int *p, int num, int total)
{
int temp = 0; //临时保持背包的总重量
int count = 0; //解的个数
int sum = 0;
//找到每个最优解
while (1){
//排列组合定理,2^n == Cn^0+Cn^1+...+Cn^n
for (int i = 0; i < num; i++){//i定位每次取多少个数
for (int j = i; j < num; j++){//j定位每次的基数
//只取一个数,当前循环就跳过
temp = 0; //重置
//根据i来取相应的i-1个数
for (int l = 0; l < i; l++){
temp += p[j - i + l];//j-i确定起点
}
sum = 0;//重置
for (int k = j; k < num; k++){//k就具体到哪些数了
sum += temp + p[k];
if (total == sum){//找到一个解
count++;
printf("第%d种组合方式为:\n",count);
for (int m = 0; m < i; m++){
printf("%3d",p[j - i + m]);//输出i-1个数,从第j个位置的数开始输出
}
printf("%3d\n",p[k]); //输出最后一个被选择的数
}else if (total < sum){//从这一点开始不符合条件,跳出此次循环
break;
}else{//这点很关键
}
sum = 0;//重置
}
if (0 == i){
j = num;//此时当前循环结束
}
}
}
if (0 == count){//如果找不出一种组合,就--total,反正就是要找出一种最大的组合方式把
--total;
}else
break;
}
}
int main(void)
{
int total,num,*p;
int sum = 0;
//总量
printf("请输入背包能承受的总重量\n");
scanf("%d",&total);
printf("请输入物品的个数\n");
scanf("%d",&num);
p = (int *)malloc(sizeof(int)*num);
if (NULL == p){
perror("malloc failed");
exit(1);
}
printf("请分别输入物品的总量\n");
for (int i = 0; i < num; i++){
scanf("%d",p + i);
sum += *(p + i);
}
printf("背包能装的下最大重量物品的组合方式为:\n");
if (total >= sum){
for (int i = 0; i < num; i++)
printf("%4d",*(p + i));
printf("\n");
}else{ //
sort(p, num);
if (total < p[0]){
printf("背包太小,容不下你的物品\n");
}else
bag(p, num, total);
}
free(p);
p = NULL;
return 0;
}