思路
1.题目要求求方案数,每个数可以重复使用,其实是完全背包模板题了,状态转移方程为
代码
#include <bits/stdc++.h>
using namespace std;
const int N=5010,mod=998244353;
int f[N];
int n;
int main()
{
cin>>n;
f[0]=1;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
f[j]=(f[j]+f[j-i])%mod;
}
}
cout<<f[n];
return 0;
}
2.冷知识,打表发现数列1 2 3 5 7 11 15 22 30 42 56 77,这其实哈代拉马努金拆分数列从第二项开始的数列,不了解的自行百度。
代码
#include <iostream>
using namespace std;
typedef long long LL;
const LL mod=998244353;
LL f[5005],g[5005],dp[5005];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)f[i]=i*(3*i-1)/2;
for(int i=1;i<=n;i++)g[i]=i*(3*i+1)/2;
dp[0]=1;
for(int i=1;i<=n;i++){
for(int j=1;f[j]<=i;j++){
if(j%2==1){
dp[i]+=dp[i-f[j]];
if(g[j]<=i)dp[i]+=dp[i-g[j]];
}
else{
dp[i]-=dp[i-f[j]];
if(g[j]<=i)dp[i]-=dp[i-g[j]];
}
}
dp[i]%=mod;
if(dp[i]<0)dp[i]+=mod;
}
dp[1]=1;
cout<<dp[n]%mod<<endl;
}