G1. Playlist for Polycarp (easy version)(狀壓dp)

題目鏈接

類似的題  狀壓dp

這兩道題都是一樣的套路,通過狀壓dp將 n!優化到 2^n,相信你寫了上面那題,這題就很容易切掉了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mix = (1<<15), N = 300, mod = 1e9 + 7;
ll powmod(ll a,ll b) {ll res=1;a%=mod; 
assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int t[N], g[N], vis[mix *2];
ll dp[mix * 2][4], cnt[mix * 2], ans; 
int main()
{
	int n, T;
	scanf("%d%d", &n, &T);
	for(int i = 0; i < n; ++i)
		scanf("%d%d", &t[i], &g[i]);
	dp[0][1] = dp[0][2] = dp[0][3] = 1;
	int mx = (1<<n);
	for(int i = 0; i < mx; ++i)
	for(int j = 0; j < n; ++j)
	if(!(i>>j & 1)){
		for(int k = 1; k <= 3; k++)
		if(k != g[j])
			dp[i ^ (1<<j)][g[j]] = (dp[i ^ (1<<j)][g[j]] + dp[i][k])%mod;
		cnt[i ^ (1<<j)] = cnt[i] + t[j];
		if(cnt[i^(1<<j)] == T)
			vis[i^(1<<j)] = 1;
	}
	for(int i = 0; i < mx; ++i)
	if(vis[i]){
		for(int j = 1; j <= 3; ++j)
		ans = (ans + dp[i][j])%mod;
	}
	printf("%lld\n", ans*powmod(2,mod-2)%mod);
 } 

 

 

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