UVA 10817 - Headmaster's Headache(位运算模拟子集+dp)

这个题可被数组坑死了。 自己给自己挖坑啊


数组开到200 明显过不了。。 只有至少256.。 交了n遍。。 坑啊。。 详细描述 看代码注释。 


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define ll long long
#define maxn 150+10
#define INF 1<<30
int st[maxn];  //  第i个人能教的科目集合
int c[maxn];   //   第i个人的工资
int d[maxn][300][300];
int s,m,n;
int dp(int i, int s0, int s1, int s2){  //  第i个人 没有教过的集合s0 一个人教过的s1 两个人教过的s2
    if(i == m+n)
        return s2 == (1 << s) - 1? 0 : INF;
    int& ans = d[i][s1][s2];
    if(ans >= 0)         // 记忆化搜索
        return ans;
    ans = INF;
    if(i >= m) // 大于了m 之后 为 求职者 可以不选
        ans = dp(i+1, s0, s1, s2);
    int m0 = st[i] & s0, m1 = st[i] & s1; //把第i个人可以教的科目与没教过的求交集 和 一个人教过的求交集
    s0 ^= m0; s1 = (s1 ^ m1) | m0;// 从 s0 中的集合 去除m0 这个元素 并且加入s1中去
    s2 |= m1; // 同时把s1 去除m1  把m1 加到 s2 中去
    ans = min(ans, c[i]+dp(i+1, s0, s1, s2));
    return ans;
}
int main (){
    while(scanf("%d%d%d",&s,&m,&n) !=EOF && s){
        getchar();
        memset(st,0,sizeof(st));
        memset(c,0,sizeof(c));
        memset(d,-1,sizeof(d));
        char ch[maxn];
        for(int i = 0; i < m; i++){
            gets(ch);
            sscanf(ch,"%d",&c[i]);
            int len = strlen(ch);
            for(int j = 6; j < len; j++){
                if(isdigit(ch[j])){
                    int x;
                    sscanf(ch+j,"%d", &x);
                    st[i] = st[i] | (1 << (x-1));
                }
                while(j < len && isdigit(ch[j]))
                    j++;
            }
        }
        for(int i = m; i < n+m; i++){
            gets(ch);
            sscanf(ch,"%d",&c[i]);
            int len = strlen(ch);
            for(int j = 6; j < len; j++){
                if(isdigit(ch[j])){
                    int x;
                    sscanf(ch+j,"%d", &x);
                    st[i] |= (1 << (x-1));
                }
                while(j < len && isdigit(ch[j]))
                    j++;
            }
        }
        int ans = dp(0,(1 << s) - 1, 0, 0);
        printf("%d\n",ans);
    }
    return  0;
}


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