D -Cut Ribbon
Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Description
Polycarpus has a ribbon, its length isn. He wants to cut the ribbon in a way that fulfils the following two conditions:
After the cutting each ribbon piece should have lengtha, b orc. After the cutting the number of ribbon pieces should be maximum.Help Polycarpus and find the number of ribbon pieces after the required cutting.
Input
The first line contains four space-separated integersn, 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.
Output
Print a single number — the maximum possible number of ribbon pieces. It is guaranteed that at least one correct ribbon cutting exists.
Sample Input
Input5 5 3 2Output
2Input
7 5 5 2Output
2
題目解析:
題目說給出給出一個綢緞的長度n。然後,是三個數,a,b,c。就是表示綢緞可以剪成a,b,c的長度。求,最多可以剪多少段?
思路解析:
剛看到題的時候,把or看成and了,靠。一開始用母函數寫了一個。wrong了。之後才知道是一道dp。我們可以把n看成背包容積,把a,b,c看成不同的花費。則狀態轉移方程式為dp[i] = max(dp[i],dp[i-x]+1)(i-x>=0)表示當長度為i的時候考慮放x的性價比是多少。所以,我們可以用一個for就可以解決該問題了。
#include#include const int INF = ~0U >>2; const int N = 4e3 + 5; int n,dp[N]; void Init() { for(int i = 0;i <= n;++i) dp[i] = -INF; } int main() { int a,b,c; while(~scanf("%d%d%d%d",&n,&a,&b,&c)) { Init();dp[0] = 0;// for(int i = 1;i <= n;++i) { if(i - a>=0){ if(dp[i] < dp[i-a]+1) dp[i] = dp[i-a]+1; } if(i - b >=0){ if(dp[i] < dp[i-b]+1) dp[i] = dp[i-b]+1; } if(i - c >=0){ if(dp[i] < dp[i-c]+1) dp[i] = dp[i-c]+1; } } printf("%d\n",dp[n]); } return 0; }