题目描述
光头强强是个伐木工人,有天他趁着熊三和熊四不在,又来砍树啦!
他现在把一棵高为n的树砍倒了,但因为树太大了实在不好搬,所以他打算把这棵树砍成若干段。而他的老板是有要求的,只收长度为a或者长度为b或者长度为c的三种型号的木段,现在他希望最后得到的木段的数量尽可能的多。光头强强是个节俭的人,所以他希望树恰好被分完,不能有剩余边角料,如果不能分完则输出0。
输入格式
一行四个整数 n,a,b,c(1\le n,a,b,c\le 10000001≤n,a,b,c≤1000000)
输出格式
一个整数代表木段数量的最大值。
样例输入
5 5 3 2
样例输出
2
很明显,这是是一道dp,而且是完全背包,第一感是搜索,只有30分,加了记忆化也只有50分,于是转
战dp。
状态定义:
f [ i ] 代表高为i时能分成的最大段数,因为题目中的n不是很大,所以这样标记没有问题。
初始化:
将f [ a ],f [ b ] , f [ c ] 设为1,因为这样才能保证在枚举到的i大于其时,不会为0。
状态转移方程:
如果i大于a,那么将原来的值与 f [ i - a ]取max,b与c同理。
最后,献上伪代码:
#include<iostream>
using namespace std;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
//定义变量
//初始化
for(int i=1;i<=n;i++)
{
//使用状态转移方程
}
//输出
return 0;
}