程序设计思维与实践 Week11 作业F

本文详细解析了背包问题的解决思路,通过实例演示如何使用动态规划算法找到最大价值的物品组合,并提供了完整的C++代码实现。文章还介绍了如何记录选取过程,以便输出具体的选择结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:

在这里插入图片描述
输入

在这里插入图片描述

输出:

在这里插入图片描述
样例:

输入:
5 3 1 3 4
10 4 9 8 4 2
20 4 10 5 7 4
90 8 10 23 1 2 3 4 5 7
45 8 4 10 44 43 12 9 8 2

输出:
1 4 sum:5
8 2 sum:10
10 5 4 sum:19
10 23 1 2 3 4 5 7 sum:55
4 10 12 9 8 2 sum:45

思路:

即背包问题,其中每张唱碟的为一种物品,唱碟的时间同时为物品的重量和价值,求能满足的最大的价值。不过在其中要记录下选取最大价值的是哪些物品。在这里用了一个vis[i][j]的数组,表示在第i轮时容积为j的时候,即判断到前i个物品的时候的是否选取,如果选取了则记录为。之后从满背包的时候,依次往回判断,如果第i个物品选取了,背包容量减少a[i]。然后i–,即判断上一个是否选取了。直到所有的i的状态和j的状态判断结束。

代码:

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
 
int N,M;  //总时间,总的唱片的数量 N<=10000 M<=20
int a[25]; 
int f[10050];    //记录总花费时间 
int b[25];        //记录已选择的点 
int vis[25][10050];  //记录该点是否选择 


int main(){
	ios::sync_with_stdio(0);
	while(cin>>N>>M){
		memset(f,0,sizeof(f));
		memset(vis,0,sizeof(vis));
		for(int i=1; i<=M; i++){
			cin>>a[i];
		}
		
		for(int i=1;i<=M;i++){
			for(int j=N;j>=0;j--){
				if(j-a[i]>=0){
									if(f[j]<=f[j-a[i]]+a[i]){ 
						f[j]=f[j-a[i]]+a[i];
						vis[i][j]=1;  //在i,j情况下选择了当前的点 
					}
				}
			}	
		}
		
		int i=M,j=N,tot=0;
		while(i>=1 && j>=0){
			if(vis[i][j]){   
				j=j-a[i];  //减去当前已经存好的点 
				b[++tot]=a[i];
			}
			i--;  //每一轮是否选择的 
		}
		for(int i=tot;i>=1;i--)
		cout<<b[i]<<" ";
		
		cout<<"sum:"<<f[N]<<endl;
	}
	return 0;
}
				
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值