uva 10817 - Headmaster's Headache 校长的烦恼

来源:互联网 发布:json.js 编辑:程序博客网 时间:2024/06/06 02:07


题目:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=465&page=show_problem&problem=1758


显而易见的背包问题+集合动归


关键是集合不是一般的集合,每门课的状态有三种:没有老师,有了1个老师,有两个及以上。


1.我的办法是用3进制数表示


2.看了别人的题解

dp[state1][state2],只有当state1里面对应位置被填充了,才能填充state2


nextS1 = p[i] | s1,

nextS2 = (p[i] & s1) | s2

f[nextS1][nextS2] = min(f[nextS1][nextS2], f[s1][s2] + p[i])


感觉这种方非常简便。


但是他这种做法的时间复杂度比我要高一点。因为 2^8*2^8=65 536>3^8=6 561

他的状态比我多一些。


/**========================================== *   This is a solution for ACM/ICPC problem * *   @source: uva 10817 Headmaster¡¯s Headache *   @type:  dp *   @author: wust_ysk *   @blog:  http://blog.csdn.net/yskyskyer123 *   @email: 2530094312@qq.com *===========================================*/#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<sstream>#include<vector>#define ysk(x)  (1<<(x))using namespace std;typedef long long ll;const int INF =0x3f3f3f3f;const int maxn= 120   ;//const int maxV=12    ;int sub,m,n;string s;int sal[maxn+5];vector<int> ab[maxn+5];const int maxed= 6561-1;//3^8int fac[]={1,3,9,27,81,243,729,2187,6561};int dp[ maxed+5],ed;int  get(int s,int x){    s/=fac[x];    return s%3;}int addst(int  s,int x){    int num=get(s,x);    if(num==2)  return s;    s+=fac[x];    return s;}int main(){    int x;    while(~scanf("%d%d%d",&sub,&m,&n)&&(m+n+sub))    {        getchar();        int st=0,ret=0;        ed=fac[sub]-1;        for(int i=1;i<=m+n;i++)        {            getline(cin,s);            stringstream ss(s);            ss>>sal[i];            if(i<=m)  ret+=sal[i];            ab[i].clear();            while(ss>>x)            {                x--;                ab[i].push_back(x);                if(i<=m) st=addst( st,x);            }        }        memset(dp,0x3f,fac[sub] *sizeof dp[0]);        dp[st]=ret;        for(int i=m+1;i<=m+n;i++)        {            for(int s=ed;s>=st;s--)            {                int s2=s;                for(int j=0;j<ab[i].size();j++)                {                    int x=ab[i][j];                    s2=addst(s2,x);                }                dp[s2]=min(dp[s2],dp[s]+sal[i]);            }        }        printf("%d\n",dp[ed]);    }   return 0;}



0 0
原创粉丝点击