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

博客介绍了如何使用状态压缩动态规划解决UVA10817问题。校长需确保s门课程每门至少有两位老师,现有m名不可解雇的老师,n名应聘者带着课程和价格。目标是最小化成本。解题思路涉及用集合s1和s2表示每门课程的师资情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接


题目大意:校长需要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 0x3f3f3f3f
const 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) );
    } 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值