https://codeforc.es/contest/1185/problem/G1

不难想到用二进制表示第i首歌选还是不选,d[s][t]表示当状态为s且最后一首歌的类型为t的方案数。

 1 #define bug(x) cout<<#x<<" is "<<x<<endl
 2 #define IO std::ios::sync_with_stdio(0)
 3 #include <bits/stdc++.h>
 4 #define iter ::iterator
 5 //#define pa pair<int,int>
 6 using namespace  std;
 7 #define ll long long
 8 #define mk make_pair
 9 #define pb push_back
10 #define se second
11 #define fi first
12 #define ls o<<1
13 #define rs o<<1|1
14 ll mod=1e9+7;
15 const int inf=2e9+10;
16 const int N=(1<<15)+5;
17 int n,T;
18 ll d[N][4];
19 int t[20],g[20];
20 ll cal(ll x,ll y){
21     ll res=1;
22     while(y){
23         if(y&1)res=res*x%mod;
24         x=x*x%mod;
25         y>>=1;
26     }
27     return res;
28 }
29 int main(){
30     IO;
31     cin>>n>>T;
32     for(int i=0;i<n;i++){
33         cin>>t[i]>>g[i];
34     }
35     int mx=(1<<n);
36     //d[0][1]=d[0][2]=d[0][3]=1;
37     d[0][0]=1;
38     for(int s=0;s<mx;s++){
39         for(int i=0;i<=3;i++){
40             for(int j=0;j<n;j++){
41                 if(!((s>>j)&1)){
42                     if(g[j]!=i){
43                         int ns=s^(1<<j);
44                         d[ns][g[j]]=(d[ns][g[j]]+d[s][i])%mod;
45                         //printf("ns=%d d=%d\n",ns,d[ns][g[j]]);
46                     }
47                 }
48             }
49         }
50     }
51     ll ans=0;
52     for(int s=0;s<mx;s++){
53         int x=s;
54         int h=0;
55         int res=0;
56         while(x){
57             if(x&1)res+=t[h];
58             x>>=1;
59             h++;
60         }
61         if(res==T){
62             for(int j=1;j<=3;j++){
63                 //printf("s=%d d=%d\n",s,d[s][j]);
64                 ans=(ans+d[s][j])%mod;
65             }
66         }
67     }
68     cout<<ans<<endl;
69 }
02-12 23:11