Polycarpus has a ribbon, its length is n. He wants to cut the ribbon in a way that fulfils the following two conditions:
- After the cutting each ribbon piece should have length a, b or c.
- After the cutting the number of ribbon pieces should be maximum.
Help Polycarpus and find the number of ribbon pieces after the required cutting.
The first line contains four space-separated integers n, a, b and c (1 ≤ n, a, b, c ≤ 4000) — the length of the original ribbon and the acceptable lengths of the ribbon pieces after the cutting, correspondingly. The numbers a, b and c can coincide.
Print a single number — the maximum possible number of ribbon pieces. It is guaranteed that at least one correct ribbon cutting exists.
5 5 3 2
2
7 5 5 2
2
In the first example Polycarpus can cut the ribbon in such way: the first piece has length 2, the second piece has length 3.
In the second example Polycarpus can cut the ribbon in such way: the first piece has length 5, the second piece has length 2.
题意:一块长为n的布,现在要把它剪开,只能剪成a, b, c这样的小块布,求最多能剪成多少块。。。
分析:就是一个需要刚好装满的完全背包问题,只有三种商品a, b, c,能取无限件物品,每件物品价值是1,求最大价值。。。。
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
int INF = 1e9+7;
const int maxn = 4e4+7;
int n, a[3], dp[maxn];
int main()
{
scanf("%d%d%d%d", &n, &a[0], &a[1], &a[2]);
dp[0] = 0;
for(int i = 1; i <= n; i++) dp[i] = -INF; //刚好装满的背包,dp[0] = 0, dp[1..n] = -INF
for(int i = 1; i <= n; i++)
for(int j = 0; j < 3; j++)
if(i >= a[j]) dp[i] = max(dp[i], dp[i - a[j]] + 1);
printf("%d\n",dp[n]);
return 0;
}