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.
一个绳子,可以分成a,b,c长度,最多分成多少段?
一开始的暴力方法,全分成a,b,c的段数,然后暴力判断,然后超时- -。接着就是剪枝,贪心的想法,并且缩小b,c段数,即确定a之后再求b,c的段数
如果有,最大段数就是这个。然而有反例,比如53,10,11,23.那么在3个10,一个23就会退出,实际上2个10,3个11才是最优解。因此在判断b,c段的时候不可以跳出,而是用max来找。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int max(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int i, j, m, n, a, b, c, ans, pre1, pre2, pre3, k, temp, leap = 0, temp1;
ans = 0;
cin >> n >> a >> b >> c;
if (a > b){ temp = a; a = b; b = temp; }
if (b > c){ temp = b; b = c; c = temp; }
if (a > b){ temp = a; a = b; b = temp; }
pre1 = n / a;
if (n%a == 0)
ans = n / a;
else
{
for (i = pre1; i >= 0; i--)
{
temp = n - a*i;
if (temp%b == 0)
{
ans = max(ans, temp / b + i);
}
else{
pre2 = temp / b;
for (j = pre2; j >= 0; j--)
{
temp1 = temp - b*j;
if (temp1%c == 0)
{
ans = max(ans, i + j + temp1 / c);
break;
}
}
}
}
}
cout << ans << endl;
return 0;
}
2.网上用的是dp法,看的我眼都要瞎了。离散化dp,然后dp[i+a]=max(dp[i+a],dp[i]+1);
然后最后输出dp[n],还需多练。还有就是从前向后找需要注意数组大小的问题,或者加一个判断if(i+a<=n)
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int dp[100000];
int max(int a, int b)
{
return a>b ? a : b;
}
int main()
{
int a, b, c, n, i, j;
cin >> n >> a >> b >> c;
memset(dp, 0, sizeof(dp));
dp[a] = dp[b] = dp[c] = 1;
for (i = 1; i <= n; i++)
{
if (dp[i])
{
dp[i + a] = max(dp[i + a], dp[i] + 1);
dp[i + b] = max(dp[i + b], dp[i] + 1);
dp[i + c] = max(dp[i + c], dp[i] + 1);
}
}
cout << dp[n] << endl;
return 0;
}