当前位置: 代码迷 >> 综合 >> bzoj 1569: [JSOI2008]Blue Mary的职员分配
  详细解决方案

bzoj 1569: [JSOI2008]Blue Mary的职员分配

热度:60   发布时间:2023-10-29 10:28:24.0

题意

由于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;
}
  相关解决方案