Linking
题意:
牛牛有
m
m
m 种类型的牌,每种牌的分值是
a
1
,
a
2
…
a
m
a_1,a_2\dots a_m
a1,a2…am。
初始分值为
0
0
0,每回合打出一张牌,新的分值就为上一回合得分加上这张牌的分值再对
k
k
k 取模。
问,有多少种出牌方案,使得
n
n
n 回合后,分值中含有字符
7
7
7 或字符
9
9
9 ?
(
1
≤
n
≤
100
,
1
≤
m
,
k
≤
50
,
0
≤
a
m
<
k
)
(1≤n≤100,1\le m,k \le50,0\le a_m < k)
(1≤n≤100,1≤m,k≤50,0≤am<k)
思路:
取模后再相加 等价于 相加后最后再取模。
所以,就先按每取模的算,最后取模再判断是否含有7或9。
求方案数,dp经典问题。
状态表示: f[i,j]
:前 i
个回合,所得分值为 j
的出牌方案数。
状态转移:
当前状态由上一回合的状态转移过来,但是并不知道当前回合出牌种类,所以还要遍历所有种类 j
:f[i,j] += f[i-1, t-a[j]]
。
初始化:0 回合得到分值为 0 的方案数f[0,0] = 1
。
Code:
const int N = 5010, mod = 1e9+7;
int T, n, m;
int a[N];
int f[N][N];
signed main(){
int k;
cin>>n>>m>>k;
for(int i=1;i<=m;i++) cin>>a[i];
sort(a+1,a+m+1);
f[0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int t=a[j];t<=n*k;t++)
{
f[i][t] += f[i-1][t-a[j]];
f[i][t] %= mod;
}
}
}
int ans=0;
for(int i=1;i<=n*k;i++){
if((i%k)%10==7 || (i%k)%10==9) ans = (ans+f[n][i])%mod;
}
cout<<ans;
return 0;
}
竟然做出来了,挺兴奋的!