UVA10817[Headmaster's Headache] 状态压缩动态规划

来源:互联网 发布:tomcat 1099端口 编辑:程序博客网 时间:2024/06/06 19:39

题目链接


题目大意:校长需要s门课,每门至少有两名老师来教,所以他现在想要招老师啦。当然,校长手头本来就有m个老师,每个老师都教着一个或多个课程,这些老师是不能解雇的,必须用。然后现在又n个老师来应聘,每个都有价格和他们能教的课程,校长希望花最少的钱达到他的目标,问:最少多少钱呢?

这里写图片描述


解题报告:

dp[s1][s2]来表示第i节课,有1个老师教的集合s1,有2个老师教的集合s2,最小的花费。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>using namespace std;#define Inf 0x3f3f3f3fconst int N = 150;const int maxs = 9;int S, n, m;int C[N], st[N];int dp[N][1<<maxs][1<<maxs];int d( int i, int s0, int s1, int s2){    if( i==m+n ) return s2==(1<<S)-1?0:Inf;    int& ans=dp[i][s1][s2];    if( ans>=0 ) return ans;    ans=Inf;    if( i>=n ) ans=d(i+1,s0,s1,s2);      int m1=st[i]&s0, m2=st[i]&s1;    s0^=m1; s1=(s1^m2)|m1; s2|=m2;    ans=min(ans, C[i]+d(i+1,s0,s1,s2) );    return ans;     }int get(){    int x=0; char ch=getchar();    while( ch!='\n' ){        if( isdigit(ch) ) x+=1<<(ch-'1');        ch=getchar();    }     return x;}int main(){    while( scanf("%d%d%d", &S, &n, &m)==3 && S ){        for ( int i=0; i<n+m; i++ ){            int x, y;            scanf("%d", &C[i]);            st[i]=get();        }        memset(dp,-1,sizeof(dp));        printf("%d\n", d(0,(1<<S)-1,0,0) );    } }
原创粉丝点击