Description
wpf深知买仔排的不易(食堂好黑的!),于是经过深思熟虑,wpf决定自己卖仔排!想我们wpf可是从事经济研究的,做买卖可难不倒wpf!经过几个日夜的钻研,wpf得出一个很重要的结论:低价买,高价卖。一块仔排进价只有1元,如果以2元卖出,不就赚钱了嘛!接下来,就要考虑运货问题了。手推车既轻便又环保,乃是居家旅行做生意之必备武器,正巧wpf就有一辆。每次,他都可以去批发商那里运一车仔排到常外去。可惜wpf力气有限,一次只能运最多K块仔排(手推车很轻,重量不计),再多wpf就推不动了。最开始,wpf手中有
Input
输入只有一行,包含了3个整数,依次为N,
N表示做生意的天数,
N≤100,X≤100,K≤50,V≤100
Output
输出一个整数,表示N天后wpf手中最多的现金数量。
Sample Input
8 5 1 5
Sample Output
10
提示
第一天买进一个仔排,花掉一块钱,手上还有4块钱。
第二天吃掉一个仔排,最大装货值变为2。
第三天买2个仔排,剩下2块钱。
第四天卖2个仔排,手上有6块钱。
第五到八天重复这一过程。
最后是10块钱。
这是最优方案。
HINT
DP
思路
看到数据范围,这道题时间复杂度肯定不小。实际上这道题的时间复杂度是
如果买入仔排:
如果卖出仔排:fi,j,k=max(fi,j,k,fi−1,L,k+(L−j)∗2)(其中L为变量,
如果吃掉仔排:fi,j,k=max(fi,j,k,fi−1,j−L,k+L)(其中L为变量,
这三个转移方程应该很好理解吧,注意一点:如果出现了负数是不行的,必须把这个较小的负数换成一个极大的负数(−inf),避免后面的状态由这个负数转移过来。
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
const int maxn=100;
const int inf=2000000000;
int n,x,m,v,ans;
int f[maxn+10][maxn+10][maxn+10];
int main()
{
scanf("%d%d%d%d",&n,&x,&m,&v);
memset(f[0],128,sizeof f);
f[0][0][std::min(v,m)]=x;
for(int i=1; i<=n; i++)
{
for(int j=0; j<=v; j++)
{
for(int k=j; k<=v; k++)
{
for(int l=0; l<=j; l++)
{
f[i][j][k]=std::max(f[i][j][k],f[i-1][l][k]-(j-l));
}
for(int l=j; l<=k; l++)
{
f[i][j][k]=std::max(f[i][j][k],f[i-1][l][k]+(l-j)*2);
}
for(int l=0; l<=std::min(v-j,k); l++)
{
f[i][j][k]=std::max(f[i][j][k],f[i-1][j+l][k-l]);
}
if(f[i][j][k]<0)
{
f[i][j][k]=-inf;
}
}
}
}
for(int i=0; i<=v; i++)
{
for(int j=0; j<=v; j++)
{
ans=std::max(ans,f[n][i][j]);
}
}
printf("%d\n",ans);
return 0;
}