0
点赞
收藏
分享

微信扫一扫

E-CD(01背包+记忆化搜索)

未定义变量 2022-02-06 阅读 96

You have a long drive by car ahead. You have a tape recorder, but unfortunately your best music is on CDs. You need to have it on tapes so the problem to solve is: you have a tape N minutes long. How to choose tracks from CD to get most out of tape space and have as short unused space as possible

Assumptions:

• number of tracks on the CD does not exceed 20

• no track is longer than N minutes

• tracks do not repeat

• length of each track is expressed as an integer number

• N is also integer Program should find the set of tracks which fills the tape best and print it in the same sequence as the tracks are stored on the CD

Input:

Any number of lines. Each one contains value N, (after space) number of tracks and durations of the tracks. For example from first line in sample data: N = 5, number of tracks=3, first track lasts for 1 minute, second one 3 minutes, next one 4 minutes

Output :

Set of tracks (and durations) which are the correct solutions and string ‘sum:’ and sum of duration times.

Sample Input:

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

Sample Output:

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

思路:

本题是典型的01背包问题,但要考虑记忆化搜索,对选择的物品要用一个数组来储存他是否选择。

代码

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,T,t[100000],dp[30][100000],ap[30][100000]={0},a[100000];
	ap表示是否选择该物品 
	while(scanf("%d%d",&T,&n)!=EOF){
	    for(int i=1;i<=n;i++)cin>>t[i];
	    for(int i=1;i<n;i++)dp[i][0]=0;//初始化 
	    for(int j=0;j<=T;j++){
	    	dp[0][j]=0;
	    	ap[0][j]=1;//初始化0件物品时,容量为j值为1; 
		}
	    for(int i=1;i<=n;i++){
	    	for(int j=1;j<=T;j++){
	    		ap[i][j]=0;
	    		if(j<t[i])dp[i][j]=dp[i-1][j];
	    		else{
			       dp[i][j]=max(dp[i-1][j],dp[i-1][j-t[i]]+t[i]);
			       if(dp[i-1][j]!=dp[i][j])ap[i][j]=1;//选择第i件物品 
			    }
			}
		}
		int maxvalue=dp[n][T];
		int cnt=0;
		for(int i=n,j=T;i>=1;i--){
			if(ap[i][j]==1){
			  a[cnt]=t[i];
			  cnt++;
			  j-=t[i];
		     }
		}//从容量为T开始找,如果ap为1则减掉该物品的容积。 
		for(int i=cnt-1;i>=0;i--)printf("%d ",a[i]);
		printf("sum:%d\n",maxvalue);
    }
    return 0;
}

举报

相关推荐

0 条评论