题目链接
类似的题 状压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);
}