p1280 破锣乐队(二维费用的背包)

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/84569961

题目

https://www.luogu.org/problemnew/show/P2736

题解

1.这是一道二维费用的背包。(看到这种题,一旦知道了他要用背包来写,用哪种背包来写,基本就解决了。)
2.唯一不同的是:此题的状态转移方程比较不同。

//j代表光碟的数量,k代表这张光碟还有多长时间来录制歌曲
f[j][k] = max ( f[j][k] , //原封不动
			max ( f[j-1][t] + 1 , //多增加一张光碟 
				f[j][k-a[i]] + 1) );//不增加光碟

应该是能明白的。
若是不明白,就把他带到代码里看看,手动模拟一下,应该就可以了。

代码

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int f=1,num=0;
	char ch=getchar();
	while (ch<'0'||ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
	while (ch>='0'&&ch<='9') num=(num<<1)+(num<<3)+ch-'0', ch=getchar();
	return num*f;
}
int f[21][21],a[21];
int main()
{	
	int n = read() , t = read() , m = read();
	for (int i = 1;i <= n; ++i)
		a[i]=read();
	for (int i = 1;i <= n; ++i)//因为需要按照顺序,所以需要逐个找
		for (int j = m;j >= 1; --j)//这个是01背包,每首歌只能录一次,
							//不可以自己叠加自己的,所以只能从后往前
			for (int k = t;k >= a[i]; --k)//和前面一样的道理,这一句和上一句换一下应该也
									//没有问题,只是这样好解释一点
				f[j][k] = max ( f[j][k] , max ( f[j-1][t] + 1 , f[j][k-a[i]] + 1) );
							//原封不动 	多增加一张光碟 	 不增加光碟
	printf("%d\n" , f[m][t]);//第m个光碟t内存最多能存多少首歌
	return 0;
}

神要是公然去跟人作对,那是任何人都难以对付的。——《荷马史诗》

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/84569961