hihCoder - 1137 : Recruitment - (背包)

题目链接:http://hihocoder.com/problemset/problem/1137

题意:有N个员工来面试,已知每个人的价值和薪水,公式收人的要求是:1.要x男y女,2.这x+y个员工的总薪水不能超过B,3.在前两点的前提上要是要使总价值最大,基于此还要使总薪水最小。4.如果答案不唯一,选择员工编号的字典序最小的方案。

要求输出选择员工的总价值和总薪水,并且输出他们的编号。

解析:本来看到总共就100的数据,就去深搜,结果超时很多,看到题解是背包的题目,感觉是很好的题目,希望以后遇到这种题能A出来,下面题解讲的很好,题解:hiho一下第83周《Recruitment》题目分析

代码:

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define M 105
int n,x,y,b;
struct node{
    int v,s,id;
}mlist[M],flist[M];
int totv,tots,mp[1005],fp[1005];//p[v]表示总薪水不超过v时,获得最大价值的总薪水值。
int maleNum,femaleNum;
int mf[M][M][1005]; //表示前i个男员工中选择j个,总薪水恰好为k的价值。若不存在合法方案,价值为0。
int ff[M][M][1005]; //表示前i个女员工中选择j个,总薪水恰好为k的价值。若不存在合法方案,价值为0。
int mg[M][M][1005]; //若mf[i][j][k]存在合法方案,则g[i][j][k]表示该方案中最后选取的员工序号,否则为-1。
int fg[M][M][1005]; //若ff[i][j][k]存在合法方案,则g[i][j][k]表示该方案中最后选取的员工序号,否则为-1。
vectorans;
int main()
{
    int i,j,k;
    char op;
    scanf("%d%d%d%d",&n,&x,&y,&b);
    maleNum=femaleNum=0;
    getchar();
    for(i=1;i<=n;i++)
    {
        scanf("%c%d%d",&op,&j,&k);
        if(op=='M')
        {
            maleNum++;
            mlist[maleNum].id=i;
            mlist[maleNum].v=j;
            mlist[maleNum].s=k;
        }else{
            femaleNum++;
            flist[femaleNum].id=i;
            flist[femaleNum].v=j;
            flist[femaleNum].s=k;
        }
        getchar();
    }



    //先处理男方

    memset(mf,0,sizeof(mf));
    memset(mg,-1,sizeof(mg));
    mg[0][0][0]=0;
    //dp求mf数组
    for(i=1;i<=maleNum;i++)
    {
        for(j=0;j<=x;j++)
        {
            for(k=0;k<=b;k++)
            {
                mf[i][j][k]=mf[i-1][j][k];
                mg[i][j][k]=mg[i-1][j][k];
                if(j>0&&k>=mlist[i].s&&mg[i-1][j-1][k-mlist[i].s]!=-1&&mf[i][j][k]0)
            mp[i]=mp[i-1];
        if(mg[maleNum][x][i]!=-1)
        {
            if(mp[i]==-1)
            {
                mp[i]=i;
            }
            else
            {
                if(mf[maleNum][x][i]>mf[maleNum][x][mp[i]])
                {
                    mp[i]=i;
                }
            }
        }
    }



    //处理女方

    memset(ff,0,sizeof(ff));
    memset(fg,-1,sizeof(fg));
    fg[0][0][0]=0;
    //dp求ff数组
    for(i=1;i<=femaleNum;i++)
    {
        for(j=0;j<=y;j++)
        {
            for(k=0;k<=b;k++)
            {
                ff[i][j][k]=ff[i-1][j][k];
                fg[i][j][k]=fg[i-1][j][k];
                if(j>0&&k>=flist[i].s&&fg[i-1][j-1][k-flist[i].s]!=-1&&ff[i][j][k]0)
            fp[i]=fp[i-1];
        if(fg[femaleNum][y][i]!=-1)
        {
            if(fp[i]==-1)
            {
                fp[i]=i;
            }
            else
            {
                if(ff[femaleNum][y][i]>ff[femaleNum][y][fp[i]])
                {
                    fp[i]=i;
                }
            }
        }
    }

    //计算怎么将总薪水b分配给男女两边
    tots=totv=0;
    for(i=0;i<=b;i++)
    {
        if(mp[i]!=-1&&fp[b-i]!=-1&&totv0)
    {
        i=mg[i][j][k];
        ans.push_back(mlist[i].id);
        j=j-1;
        k=k-mlist[i].s;
        i=i-1;
    }
    //女方选中人员
    i=femaleNum; j=y; k=fp[b-tots];
    while(j>0)
    {
        i=fg[i][j][k];
        ans.push_back(flist[i].id);
        j=j-1;
        k=k-flist[i].s;
        i=i-1;
    }

    printf("%d %d\n",totv,mp[tots]+fp[b-tots]);
    sort(ans.begin(),ans.end());
    vector::iterator it;
    for(it=ans.begin();it!=ans.end();it++)
    {
        printf("%d ",*it);
    }
    printf("\n");
    return 0;
}

超时深搜:

#include 
#include 
#include 
#include 
using namespace std;
#define M 105
int n,x,y,b;
struct node{
    char g;
    int v,s;
}a[M];
int totV,totS;
bool vis[M],temp[M];
void dfs(int it,int m,int f,int tv,int ts)// 该考虑it号应聘者,已经选了m男,f女,总能力值为tv,总工资为s
{
    if(ts>b||m>x||f>y)
        return;
    if(m==x&&f==y)
    {
        if(tv>totV)
        {
            totV=tv;
            totS=ts;
            for(int i=1;i<=n;i++)
                vis[i]=temp[i];
        }
        return;
    }
    for(int i=it;i<=n;i++)
    {
        if(a[i].s>b)
            continue;
        if(a[i].g=='M')
        {
            if(m



你可能感兴趣的:(动态规划)