uva 10817 - Headmaster's Headache ( 状态压缩dp)

本文解决UVA10817-Headmaster's Headache问题,通过动态规划算法实现最少成本安排教师授课,确保每门课程至少由两位教师教授。

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



本文出自   http://blog.youkuaiyun.com/shuangde800



题目链接: 点击打开链接


题目大意

某校有n个教师和m个求职者,已知每人的工资和能教的课程集合,要求支付最少的工资使得每门课都至少有两名教师教学。在职教师必须招聘。


思路

这题不太好想,搞了很久。。

f[s1][s2]: s1表示课程集合{ s1 }都至少有一个教师教的情况。

               s2表示课程集合{ s2 }都至少有两个教师教的情况。


每个求职者的pi, 对于每个求职者,要么选,要么不选,就是01背包问题。

对于s1,s2,可以根据当前枚举到的求职者课程即可,可推出下一个状态:

nextS1 = p[i] | s1,

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

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



代码

/**==========================================
 *   This is a solution for ACM/ICPC problem
 *
 *   @problem: UVA 10817 - Headmaster's Headache
 *   @type:  dp
 *   @author: shuangde
 *   @blog: blog.youkuaiyun.com/shuangde800
 *   @email: zengshuangde@gmail.com
 *===========================================*/

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
#include
       
       
         #include 
        
          #include 
         
           using namespace std; typedef long long int64; const int INF = 0x3f3f3f3f; const double PI = acos(-1.0); const int MAXN = 150; int courseNum, m, n, sum; int maxState; int f[1<<8][1<<8]; int p[MAXN], c[MAXN], cnt[10]; int dp(int st1, int st2){ memset(f, 0x3f, sizeof(f)); f[st1][st2] = sum; for(int i=m+1; i<=n+m; ++i){ for(int s1=maxState; s1>=0; --s1){ for(int s2=maxState; s2>=0; --s2){ if(f[s1][s2] >= INF) continue; int st1 = (p[i]|s1); int st2 = (p[i]&s1) | s2; f[st1][st2] = min(f[st1][st2], f[s1][s2]+c[i]); } } } return f[maxState][maxState]; } int main(){ char str[1000]; while(~scanf("%d%d%d", &courseNum, &m, &n) && courseNum){ maxState = (1< 
          
            1) st2 |= (1< 
            
           
          
         
       
      
      
     
     
    
    
   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值