题意
由于Blue Mary呕心沥血的管理,Blue Mary的网络公司蒸蒸日上。现在一共拥有了n名职员,可惜没有任何的金钱和声誉。平均每名每天职员都可以给公司带来x单位金钱或者y单位声誉(名利不能双全)。并且可以花费z单位的金钱在人才交易市场发布广告招聘职员,每次发布广告三天以后就会招聘到一名职员,并且必须在发布广告并且招聘到职员的那一天才能发布下一次广告。 Blue Mary计划以最快的时间获得至少A单位金钱和至少B单位声誉,请你计算一下他至少需要多少时间才能达到他的目标。
题解
这题其实挺简单的,但是还是想了一会
终于重新学会自己想题了
你就f[i][j][k]来表示现在有i个人,经济和声望状态所用的最少天数就可以了
很容易知道,不会超过20个人,声望可以对20取min,经济可以对20*7取min,于是就可以跑过去了
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int MAX=(1<<28);
const int N=22;
int f[N][N*8][N];//现在有i个人 j点名誉 k块钱最少需要多少天
int n,x,y,z,A,B;//一开始有多少人 x块钱 y单位名誉 买人的价钱 目标
void DOWN (int &a,int b)
{
if (a>b) a=b;
}
int main()
{
scanf("%d %d %d %d %d %d",&n,&x,&y,&z,&A,&B);
for (int u=n;u<=20;u++)
for (int i=0;i<=20*8;i++)
for (int j=0;j<=20;j++)
f[u][i][j]=MAX;
f[n][0][0]=0;
for (int u=n;u<=20;u++)
for (int i=0;i<=20*8;i++)
for (int j=0;j<=20;j++)
if (f[u][i][j]<MAX)
{
/*什么人都不招*/
for (int k=0;k<=u;k++)//有多少人去生产钱
DOWN(f[u][min(20*8,i+k*x)][min(20,j+(u-k)*y)],f[u][i][j]+1);
/*什么人都不招*/
if (i>=z)//尝试招一个人
{
int X=i-z,Y=j;
for (int k=0;k<=3*u;k++)//分配多少人去生产钱
DOWN(f[min(u+1,20)][min(20*8,X+k*x)][min(20,Y+((3*u)-k)*y)],f[u][i][j]+3);
}
}
int ans=MAX;
for (int u=n;u<=20;u++)
for (int i=A;i<=20*8;i++)
for (int j=B;j<=20;j++)
ans=min(ans,f[u][i][j]);
printf("%d\n",ans);
return 0;
}