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

题意

由于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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值