现在的位置: 首页 > 综合 > 正文

uva10817

2013年08月24日 ⁄ 综合 ⁄ 共 1109字 ⁄ 字号 评论关闭

定义状态dp[i][s]表示把雇佣前i个应聘者到达s这个状态的最小费用

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 6e8;
const int N = 6561*3;
int dp[N],num_s[10],top,fare,s,n,m,pow_3[10];
int num_convert()//把数组转化为10进制整数
{
    int ans=0,pow=1;
    for(int i=1;i<=s;i++)
    {
        if(num_s[i]>=2)
        {
            ans+=2*pow;
        }
        else
        {
            ans+=num_s[i]*pow;
        }
        pow*=3;
    }
    return ans;
}
void str_convert(char *ss)//把输入的字符串变为数组的形式
{
    char *p=ss;
    int ans,flag=0;
    while(*p!='\0')
    {
        ans=0;
        while(*p==' ')
            p++;
        while(*p!='\0'&&'0'<=*p&&*p<='9')
        {
            ans=ans*10+*p-'0';
            p++;
        }
        if(ans)
        {
            if(flag)
            {
                num_s[ans]++;
            }
            else
            {
                fare+=ans;
                flag=1;
            }
        }
    }
}
int fun(int d)//数和数组相加
{
    top=1;
    while(d)
    {
        num_s[top++]+=d%3;
        d/=3;
    }
    return num_convert();
}
int main()
{
    pow_3[0]=1;
    for(int i=1;i<9;i++)
    {
        pow_3[i]=pow_3[i-1]*3;
    }
    char ss[100];
    while(scanf("%d %d %d",&s,&n,&m)!=EOF&&s)
    {
        getchar();
        fill(dp,dp+pow_3[s],MAX);
        memset(num_s,0,sizeof(num_s));
        fare=0;
        for(int i=0;i<n;i++)//累积前n项的和
        {
            gets(ss);
            str_convert(ss);
        }
        int number=num_convert();
        dp[number]=fare;
        for(int i=1;i<=m;i++)
        {
            gets(ss);
            for(int j=pow_3[s]-1;j>=0;j--)
            {
                fare=0;
                memset(num_s,0,sizeof(num_s));
                str_convert(ss);
                number=fun(j);
                dp[number]=min(dp[number],dp[j]+fare);
            }
        }
        printf("%d\n",dp[pow_3[s]-1]);
    }
    return 0;
}

抱歉!评论已关闭.