#222-[DP,背包]玩具

27 篇文章 0 订阅

Description

      商店正在出售小C最喜欢的系列玩具,在接下来的n周中,每周会出售其中的一款,同一款玩具不会重复出现。

      由于是小C最喜欢的系列,他希望尽可能多地购买这些玩具,但是同一款玩具小C只会购买一个。同时,小C的预算只有m元,因此他无法将每一款都纳入囊中。此外,小C不能连续两周都购买玩具,否则他会陷入愧疚。现在小C想知道,他最多可以买多少款不同的玩具呢? 

Input

输入文件共2行; 
第一行两个正整数n和m,中间用一个空格隔开; 
第二行共n个正整数,第i个正整数表示第i周出售的玩具的价格。

Output

输出文件只有一行,包含一个整数,表示小C最多能买多少款不同的玩具。

3 8

4 4 5
  • Sample Input

1
  • Sample Output

HINT

【数据范围】 
对于30%的数据,n≤10; 
对于60%的数据,n≤100,m≤1000; 
对于100%的数据,n≤1000,m≤1000000,单个玩具的价格≤1000。

Source/Category

2019年海淀区挑战赛初中组  

直接DP(背包)

#include <iostream>
#include <cstdio>

using namespace std;
const int MAXN = 1000010;

int dp[3][MAXN][2]; // 滚动数组

int main() {
	int n, m; scanf("%d%d", &n, &m);
	int now=0, last1=1, last2=2;
	for (int i=1; i<=n; ++i) {
		int x; scanf("%d", &x);
		if (i==1) {
			for (int j=x; j<=m; ++j) dp[2][j][1]=1; // 边界条件买的
		}
		else if (i==2) {
			for (int j=x; j<=m; ++j) dp[1][j][1]=1; // 边界条件买的
			for (int j=0; j<=m; ++j) dp[1][j][0]=dp[2][j][1]; // 不买的
		}
		else {
			for (int j=0; j<=m; ++j) dp[now][j][0]=max(dp[last1][j][0],dp[last1][j][1]); // 不买的取前一次买的和不买的的最大值
			for (int j=0; j<=m; ++j) dp[now][j][1]=0;
			for (int j=x; j<=m; ++j) dp[now][j][1]=max(dp[last1][j-x][0], dp[last2][j-x][1])+1; // 买的用前一次不买的和前两次买的
			int tmp = last2;
			last2=last1; last1=now; now=tmp;
		}
	}
	now=last1;
	if (n==1) now=2;
	else if (n==2) now=1;
	printf("%d", max(dp[now][m][0], dp[now][m][1]));
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值