【C】背包问题

//01背包
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=100;//物品最大件数
const int maxv=1000;//容量最大值
int w[maxn],c[maxn],dp[maxv];
int main(){
	int n,V;
	cin>>n>>V;
	for(int i=1;i<=n;i++){
		cin>>w[i];
	}
	for(int i=1;i<=n;i++){
		cin>>c[i];
	}
	for(int v=0;v<=V;v++){
		dp[v]=0;
	}
	for(int i=1;i<=n;i++){
		for(int v=V;v>=w[i];v--){
			dp[v]=max(dp[v],dp[v-w[i]]+c[i]);
		}
	}
	int max=0;
	for(int v=0;v<=V;v++){
		if(dp[v]>max){
			max=dp[v];
		}
	}
	cout<<max;
	return 0;
}

问题 A: 装箱问题

时间限制: 1 Sec   内存限制: 128 MB
提交: 54   解决: 33
[ 提交][ 状态][ TK题库][命题人: ]

题目描述

【问题描述】
有一个箱子的容量为V(V为正整数,且满足0≤V≤20000),同时有n件物品(0的体积值为正整数。
要求从n件物品中,选取若干装入箱内,使箱子的剩余空间最小。
输入:1行整数,第1个数表示箱子的容量,第2个数表示有n件物品,后面n个数分别表示这n件
物品各自的体积。
输出:1个整数,表示箱子剩余空间。
【输入输出样例】
输入:
24 6 8 3 12 7 9 7
输出:
0
//问题A: 装箱问题
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=100000;//物品最大件数
const int maxv=20010;//容量最大值
int v[maxn],dp[maxv];
int main(){
	int Vmax,n,vv;
	cin>>Vmax>>n;
	int i;
	for(i=0;i<n;i++){
		cin>>v[i];
	}
	for(i=0;i<=Vmax;i++){
		dp[i]=0;
	}
	for(i=0;i<n;i++){
		for(vv=Vmax;vv>=v[i];vv--){
			dp[vv]=max(dp[vv],dp[vv-v[i]]+v[i]);
		}
	}
	int max=-1;
	for(i=0;i<=Vmax;i++){
		if(dp[i]>max){
			max=dp[i];
		}
	}
	cout<<Vmax-max;

}		

问题 B: 采药

时间限制: 1 Sec   内存限制: 128 MB
提交: 45   解决: 34
[ 提交][ 状态][ TK题库][命题人: ]

题目描述

辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。

医师为了判断他的资质,给他出了一个难题。

医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是辰辰,你能完成这个任务吗?

 【输入 】第一行有两个整数T(1 <= T <= 1000)和M(1 <= M <= 100),用一个空格隔开,

T代表总共能够用来采药的时间,M代表山洞里的草药的数目。

接下来的M行每行包括两个在1到100之间(包括1和100)的整数,分别表示采摘某株草药的时间和这株草药的价值。

【输出】一个整数,表示在规定的时间内,可以采到的草药的最大总价值。


【样例输入】

70 3

71 100

69 1

1 2

【样例输出】

3

【数据规模】

   对于30%的数据,M <= 10;

   对于全部的数据,M <= 100。


//问题 B: 采药
//想当然是完全背包问题,但是分析一下用例,是01背包
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
	int T,M,i,j;
	cin>>T>>M;
	int cost[110];//每株草药的价值
	int time[110];//每株采摘时间
	int dp[1010];
	for(i=1;i<=M;i++){
		cin>>time[i]>>cost[i];
	}
	for(j=0;j<=T;j++){
		dp[j]=0;
	}
	for(i=1;i<=M;i++){
		for(j=T;j>=time[i];j--){
			dp[j]=max(dp[j],dp[j-time[i]]+cost[i]);
			//printf("dp[%d]=%d\n",j,dp[j]);
		}
	}
	int max=-1;
	for(j=0;j<=T;j++){
		if(dp[j]>max){
			max=dp[j];
			i=j;
		}
	}
	cout<<max<<endl;
	return 0;
}

问题 C: 货币系统

时间限制: 1 Sec   内存限制: 128 MB
提交: 46   解决: 20
[ 提交][ 状态][ TK题库][命题人: ]

题目描述

母牛们不但创建了他们自己的政府而且选择了建立了自己的货币系统。
[In their own rebellious way],,他们对货币的数值感到好奇。
传统地,一个货币系统是由1,5,10,20 或 25,50, 和 100的单位面值组成的。
母牛想知道有多少种不同的方法来用货币系统中的货币来构造一个确定的数值。
举例来说, 使用一个货币系统 {1,2,5,10,...}产生 18单位面值的一些可能的方法是:18x1, 9x2, 8x2+2x1, 3x5+2+1,等等其它。
写一个程序来计算有多少种方法用给定的货币系统来构造一定数量的面值。
保证总数将会适合long long (C/C++) 和 Int64 (Free Pascal)。

输入

输入包含多组测试数据

货币系统中货币的种类数目是 V 。 (1<= V<=25)
要构造的数量钱是 N 。 (1<= N<=10,000)

第 1 行: 二整数, V 和 N
第 2 ..V+1行:可用的货币 V 个整数 (每行一个 每行没有其它的数)。

输出

单独的一行包含那个可能的构造的方案数。

样例输入

3 10
1 2 5

样例输出

10
//问题 C: 货币系统
//完全背包问题
//dp[i][j]表示用前i种表示数量j的钱
//dp[i][j]=dp[i-1][j]+dp[i-1][j-kind[i]]--不用第i种+用第i种
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
	int V,N;//货币种类、要构造的钱
	int i,j;
	while(scanf("%d %d",&V,&N)!=EOF){
		int kind[30];//货币面值
		long long dp[10010];
		for(i=1;i<=V;i++){
			cin>>kind[i];
		}
		for(j=0;j<=N;j++){
			dp[j]=0;
		}
		dp[0]=1;
		sort(kind,kind+V+1);//排序 
		for(i=1;i<=V;i++){
			for(j=kind[i];j<=N;j++){
				dp[j]=dp[j]+dp[j-kind[i]];//方法数:不用第i个+用第i个
				//printf("dp[%d]=%d\n",j,dp[j]);
			}
		}
		printf("%lld\n",dp[N]);
	}
	return 0;
}

1068. Find More Coins (30)

时间限制
150 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Eva loves to collect coins from all over the universe, including some other planets like Mars. One day she visited a universal shopping mall which could accept all kinds of coins as payments. However, there was a special requirement of the payment: for each bill, she must pay the exact amount. Since she has as many as 104 coins with her, she definitely needs your help. You are supposed to tell her, for any given amount of money, whether or not she can find some coins to pay for it.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive numbers: N (<=104, the total number of coins) and M(<=102, the amount of money Eva has to pay). The second line contains N face values of the coins, which are all positive numbers. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the face values V1 <= V2 <= ... <= Vk such that V1 + V2 + ... + Vk = M. All the numbers must be separated by a space, and there must be no extra space at the end of the line. If such a solution is not unique, output the smallest sequence. If there is no solution, output "No Solution" instead.

Note: sequence {A[1], A[2], ...} is said to be "smaller" than sequence {B[1], B[2], ...} if there exists k >= 1 such that A[i]=B[i] for all i < k, and A[k] < B[k].

Sample Input 1:
8 9
5 9 8 7 2 3 4 1
Sample Output 1:
1 3 5
Sample Input 2:
4 8
7 2 4 3
Sample Output 2:
No Solution
//01背包问题
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;	
int choice[10010][110];
bool cmp(int a,int b){
	return a>b;
}
int main(){
	int N,M,i,j;
	cin>>N>>M;
	int kind[10010];
	int dp[110];
	for(i=1;i<=N;i++){
		cin>>kind[i];
	}
	sort(kind+1,kind+N+1,cmp);
	for(i=0;i<=M;i++){
		dp[i]=0;
	}
	for(i=1;i<=N;i++){
		for(j=M;j>=kind[i];j--){
			if(dp[j]<=dp[j-kind[i]]+kind[i]){
				choice[i][j]=1;
				dp[j]=dp[j-kind[i]]+kind[i];
			}
			else choice[i][j]=0;
		}
	}
	if(dp[M]!=M) cout<<"No Solution"<<endl;
	else{
		int k=N,num=0,v=M;
		int flag[10010];
		while(k>=0){
			if(choice[k][v]==1){
				flag[k]=1;
				v-=kind[k];
				num++;
			}
			else flag[k]=0;
			k--;
		}
		for(i=N;i>=1;i--){
			if(flag[i]==1){
				cout<<kind[i];
				num--;
				if(num!=0) cout<<" ";
			}
		}
	}
	return 0;
}


输入描述:
输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格、每袋的重量以及对应种类大米的袋数。

输出描述:
对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完。每个实例的输出占一行。

示例1

输入
1
8 2
2 100 4
4 100 2

输出
400

#include<stdio.h>
#include<iostream>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<algorithm>
using namespace std;
struct PRO{
	int p,w;
};
int main(){
	int c;
	cin>>c;
	while(c--){
		PRO buf[2010];
		int dp[110];
		int n,m;
		cin>>n>>m;
		int num=1;
		for(int i=0;i<m;i++){
			int a,b,c;
			cin>>a>>b>>c;
			int k=1;
			while(c-k>0){
				c=c-k;
				buf[num].p=k*a;
				buf[num].w=k*b;
				k*=2;
				num++;
			}
			buf[num].p=c*a;
			buf[num].w=c*b;
			num++;
		}
		fill(dp,dp+110,0);
		for(int i=1;i<num;i++){
			for(int j=n;j>=buf[i].p;j--){
				dp[j]=max(dp[j],dp[j-buf[i].p]+buf[i].w);
			}
		}
		
		int max=-1;
		for(int i=0;i<=n;i++){
			if(dp[i]>max) max=dp[i];
		}
		cout<<max<<endl;
	}
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值