[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;
} 

猜你喜欢

转载自blog.csdn.net/qq_20252251/article/details/108365328
今日推荐