A1951 AC Challenge(狀壓dp)

題目鏈接

題意:有n個題目,每分鐘可以做一個題目,做一些特點題目之前要把規定的題目做了才能做,每個題目能做的貢獻是 T * a + b

T是做這個題目的時間。

題解:這題轉移簡單,就是預處理有些麻煩。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = (1 << 21); 
ll a[23], b[23];
ll dp[N], pre[N];
int t[23], F[23], sta[N];
bool cmp(int c, int d){
	return c > d;
}
int main()
{
	int n, mx, cnt;
	cin>>n;
	mx = 1 << n; 
	
	for(int i = 0; i < n; ++i){
		cin>>a[i]>>b[i]>>cnt;
		for(int j = 0; j < cnt; ++j)  cin>>t[j];
		sort(t, t + cnt, cmp);
		cnt--;
		for(int j = n; j >= 1; --j){ 
			if(cnt >= 0 && t[cnt] == j){
				cnt--;
				F[i] = (F[i]<<1) + 1;
			}else F[i] = F[i]<<1;
		}
	}
	for(int i = 0; i < mx; ++i){
		
		int flag = 1; 
		for(int j = 0; j < n; ++j)
		if((i&(1<<j)) && (i & F[j])!= F[j]) flag = 0;
		sta[i] = flag;
		
		int tmp = i;
		while(tmp){
			if(tmp%2) pre[i]++;
			tmp/=2;
		}
	}

	for(int i = 0; i < mx; ++i)
	for(int j = 0; j < n; ++j)
	if(((1<<j)&i)==0 && (i & F[j]) == F[j] && sta[i])
	dp[i^(1<<j)] = max(dp[i^(1<<j)], dp[i] + a[j]*pre[i^(1<<j)]+b[j]);
	
	printf("%lld\n", dp[mx - 1]);
}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章