传送门:数字组合
思路:状态表示:f[j]为当和为j时最大的选择方案;
状态转移方程:f[j]+=f[j-d[i]],因为能到达的和都是确定的,所以初始化f[0]=1;
一维版:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
#include<sstream>
using namespace std;
typedef long long LL;
int n,m,k;
const int N=1e6;
int f[N];
int w[N];
int v[N];
int d[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>d[i];
f[0]=1;
for(int i=1;i<=n;i++)
for(int j=m;j>=d[i];j--)
{
f[j]+=f[j-d[i]];
}
cout<<f[m]<<endl;
return 0;
}
二维版本:
#include <bits/stdc++.h>
using namespace std;
int n,m,k;
const int N=110,M=10010;
int f[N][M];
int main()
{
cin>>n>>m;
f[0][0]=1;
int v;
for(int i=1;i<=n;i++)
{
cin>>v;
for(int j=m;j>=0;j--)
{
f[i][j]=f[i-1][j];
if(j>=v)
f[i][j]+=f[i-1][j-v];
}
}
cout<<f[n][m]<<endl;
return 0;
}
传送门:买书
思路:看清题目说的钱全部用来买书。所以不能刚好花完时方案数为零。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
#include<sstream>
using namespace std;
typedef long long LL;
int n,m,k;
const int N=1e6;
int f[N];
int main()
{
int n;
int d[5]={0,10,20,50,100};
cin>>n;
f[0]=1;
for(int i=1;i<=4;i++)
for(int j=d[i];j<=n;j++)
f[j]+=f[j-d[i]];
cout<<f[n];
return 0;
}
传送门:自然数拆分
思路:和数字组合一样,不过是这次有n个,要开longlong,至少由两个数组成,最后要减1
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef long long LL;
const int N=1e5+7,mod=2147483648;
long long f[4010];
int st[N];
int main()
{
int n;
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]-1)%mod<<endl;
return 0;
}
传送门:摆花
二维版:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef long long LL;
const int N=1e4+7,mod=1000007;
long long f[N][N];
int v[N][N];
int s[N];
int main()
{
int n,m;
cin>>n>>m;
f[0][0]=1;
for(int i=1;i<=n;i++)
{
cin>>s[i];
for(int j=1;j<=s[i];j++)
v[i][j]=j;
}
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
for(int k=0;k<=s[i]&&v[i][k]<=j;k++)
f[i][j]=(f[i][j]+f[i-1][j-v[i][k]])%mod;
cout<<f[n][m]<<endl;
return 0;
}
一维版:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef long long LL;
const int N=1e4+7,mod=1000007;
long long f[N];
int v[N][N];
int s[N];
int main()
{
int n,m;
cin>>n>>m;
f[0]=1;
for(int i=1;i<=n;i++)
{
cin>>s[i];
for(int j=1;j<=s[i];j++)
v[i][j]=j;
}
for(int i=1;i<=n;i++)
for(int j=m;j>=0;j--)
for(int k=1;v[i][k]<=j&&k<=s[i];k++)
f[j]=(f[j]+f[j-v[i][k]])%mod;
cout<<f[m]<<endl;
return 0;
}