玩具
题目
商店正在出售小 C C C最喜欢的系列玩具,在接下来的 n n n周中,每周会出售其中的一款,同一款玩具不会重复出现。
由于是小 C C C最喜欢的系列,他希望尽可能多地购买这些玩具,但是同一款玩具小 C C C只会购买一个。同时,小 C C C的预算只有 m m m元,因此他无法将每一款都纳入囊中。此外,小 C C C不能连续两周都购买玩具,否则他会陷入愧疚。现在小 C C C想知道,他最多可以买多少款不同的玩具呢?
输入
输入文件共
2
2
2行;
第一行两个正整数
n
n
n和
m
m
m,中间用一个空格隔开;
第二行共
n
n
n个正整数,第
i
i
i个正整数表示第
i
i
i周出售的玩具的价格。
输出
输出文件只有一行,包含一个整数,表示小 C C C最多能买多少款不同的玩具。
样例输入
3 8
4 4 5
样例输出
1
数据范围
对于
30
%
30%
30%的数据,
n
≤
10
n≤10
n≤10;
对于
60
%
60%
60%的数据,
n
≤
100
n≤100
n≤100,
m
≤
1000
m≤1000
m≤1000;
对于
100
%
100%
100%的数据,
n
≤
1000
n≤1000
n≤1000,
m
≤
1000000
m≤1000000
m≤1000000,单个玩具的价格
≤
1000
≤1000
≤1000。
思路
这道题用
01
01
01背包做,但是要用到滚动数组。
设
f
[
i
]
[
j
]
f[i][j]
f[i][j]为在前
i
i
i样东西中你花费
j
j
j最多能买到的物品数量,就可以了。
(由于数据水,所以不会炸)
当然也有大佬用
O
(
n
2
)
O(n^2)
O(n2)的算法,本蒟蒻肯定不会打啦!
对了,滚动数组是为了处理题目要求的不能连续两周买的条件。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,a[1001],f[1000001],ans,one=1,two=2;
bool gun[3][1000001];
int main()
{
scanf("%d%d",&n,&m);//读入
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);//读入
for (int i=1;i<=n;i++)
{
swap(one,two);
for (int j=1;j<=m;j++) gun[two][j]=0;//初始化
for (int j=m;j>=a[i];j--)
if (f[j]<f[j-a[i]]+1&&!gun[one][j-a[i]])//01背包
{
f[j]=f[j-a[i]]+1;
gun[two][j]=1;//标记
}
}
printf("%d",f[m]);//输出
return 0;
}