#include <string.h> #include <stdio.h> #include <iostream> using namespace std; int dp[4050]; int main() { int n,a,b,c; while(cin >> n >> a >> b >> c) { memset(dp,-1,sizeof(dp)); dp[a]=1;dp[b]=1;dp[c]=1; for(int i=1;i<=n;i++) { if(i-a>0 && dp[i-a]!=-1 && dp[i-a]+1>dp[i]) dp[i]=dp[i-a]+1; if(i-b>0 && dp[i-b]!=-1 && dp[i-b]+1>dp[i]) dp[i]=dp[i-b]+1; if(i-c>0 && dp[i-c]!=-1 && dp[i-c]+1>dp[i]) dp[i]=dp[i-c]+1; } // for(int i=1;i<=n;i++) // { // cout << dp[i] << " "; // } cout << dp[n] << endl; } return 0; }
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.
某晚codeforces上的2房A题。
状态:dp[i]代表结到长度为i时,所能结的最大段数。
状态转移方程:dp[i]=dp[i-a]+1;
考虑三个情况:
1.减出界;
2.初始值为-1,不进行处理,因为无法形成一段的剪法,再加一块,也无法形成正确的剪法;
3.dp[i]<dp[i-a]+1,求最大的段数,所以dp[i]要比dp[i-1]存的段数多。