[bzoj1569][JSOI2008][Blue Mary的职员分配]

Description

由于Blue Mary呕心沥血的管理,Blue Mary的网络公司蒸蒸日上。现在一共拥有了n名职员,可惜没有任何的金钱和声誉。平均每名每天职员都可以给公司带来x单位金钱或者y单位声誉(名利不能双全)。并且可以花费z单位的金钱在人才交易市场发布广告招聘职员,每次发布广告三天以后就会招聘到一名职员,并且必须在发布广告并且招聘到职员的那一天才能发布下一次广告。 Blue Mary计划以最快的时间获得至少A单位金钱和至少B单位声誉,请你计算一下他至少需要多少时间才能达到他的目标。

Input

输入有且仅有一行,包含六个整数n,x,y,z,A和B,意义如题目描述所述。

Output

要求输出一行,包含一个整数,表示Blue Mary至少需要多少时间才能达到他的目标。

Sample Input

1 2 3 4 5 6

Sample Output

5

HINT

1<=n,x,y,z,A,B<=20

Solution

#include <stdio.h>
#include <memory.h>
#define inf 0x3f3f3f3f
#define dmin(a,b) ((a)<(b)?(a):(b))
#define dmax(a,b) ((a)>(b)?(a):(b))

int n,x,y,z,A,B,aa,f[35][25][25][5],ans;

inline void shift(register int a,register int b,register int c,register int d,register int i,register int j,register int k,register int p){
  if(b<0)return;
  b=dmin(b,aa);
  c=dmin(c,B);
  f[a][b][c][d]=dmin(f[a][b][c][d],f[i][j][k][p]+1);
}

int main(){
  memset(f,0x3f,sizeof(f));
  scanf("%d%d%d%d%d%d",&n,&x,&y,&z,&A,&B);
  f[n][0][0][0]=0; aa=dmax(A,z); ans=inf;
  for(register int i=n; i<=34; i++)
    for(register int p=0; p<=3; p++)
      for(register int j=0; j<=aa; j++)
    for(register int k=0; k<=B; k++)
      if(f[i][j][k][p] != inf){
        if(j >= A && k >= B){
          ans=dmin(ans,f[i][j][k][p]);
          continue;
        }
        if(f[i][j][k][p] > ans)
          continue;
        for(register int q=0; q<=i; q++){
          register int xx=j+x*q,yy=k+y*(i-q),ii=i;
          if(p==3)ii++;
          if(p==3 || p==0)
        shift(ii,xx,yy,0,i,j,k,p),shift(ii,xx-z,yy,1,i,j,k,p);
          else
        shift(ii,xx,yy,p+1,i,j,k,p);
        }
      }
  printf("%d
",ans);
  return 0;
}
原文地址:https://www.cnblogs.com/keshuqi/p/6308855.html