[HDU 1074|状态压缩DP]D - Doing Homework

拿到这题很容想到去暴力搜索,枚举所有路径去搜索。复杂度为O(n!)显然是不行的
将第i个符串标记为整数数字的第i位,dp[i]表示选取当前字符串最小的花费,如computer为第0位,english为第1位,math为第2位,dp[5]表示dp[101B],即选取computer和math的最小花费,而dp[5]又是由dp[1]和dp[4]更新取最小而来的。这样更新的复杂度为状态数*枚举bit位 = 2^n * n

#include<bits/stdc++.h>
#define pb push_back
#define debug(x) cout<<#x<<" is "<<x<<endl
using namespace std;
int n,m;
const int N = 5e4 + 5;
vector<string> v;
vector<int> deadline,cost;
int dp[N];
int pre[N];
int consumdays[N];
const int INF = 0x3f3f3f3f;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	while(n--){
		for(int i = 0;i < N;i++){
			dp[i] = INF;
			pre[i] = 0;
			consumdays[i] = 0;
		}
		dp[0] = 0;
		v.clear();
		deadline.clear();
		cost.clear();
		cin>>m;
		for(int i = 0;i < m;i++){
			string s;
			int d,c;
			cin>>s>>d>>c;
			v.pb(s);
			deadline.pb(d);
			cost.pb(c);
		}
		int status = (1<<m);
		for(int i = 0;i < status;i++){
			int mask = 1;
			for(int j = 0;j < m;j++){

				if((i&mask) == 0){
					int consum = (consumdays[i] + cost[j]) <= deadline[j]?0:(consumdays[i] + cost[j]) - deadline[j];		
					if(dp[i] + consum < dp[i + mask]){
						dp[i + mask] = dp[i] + consum;
						pre[i + mask] = i ;
						consumdays[i + mask] =cost[j] +  consumdays[i];
					}
				}
				mask<<=1;
				
			}
		}
		cout<<dp[status - 1]<<endl;
		vector<int> ans;
		int x = status - 1;
		while(x != 0){
			ans.pb(x - pre[x]);
			x = pre[x];

		}
		for(int i = ans.size() - 1;i >= 0;i--){
			int index = 0;
			while((ans[i]&1) != 1){
				ans[i]>>=1;
				index++;
			}
			cout<<v[index]<<endl;
		}
	}
	return 0;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值