2 条题解
-
0
写给DP新手的题解(好吧我也是蒟蒻(
首先,我们推一下式子
我们令来表示我们选择到第j元钱的方案数
那么我们枚举一个表示我们当前选了元钱的东西,然后又选了这么一个价值为i的物品
那么我们肯定要保证吧?
$\sum\limits_{i=1}^{k}\sum\limits_{j=i}^{n}f[j]+=f[j-i];$
为什么这里的是呢?
我们可以发现,当转移到的时候,已经有了一些情况(显而易见(因为在枚举之前,必定先枚举的,那么在转移的时候就不会出现像转移了,没转移的情况
但是我们又发现,这肯定是炸的
所以我们用了个小技巧——int128
这是一个能存128位的东西(应该是吧?
(但是在本地编译器会炸(别问我为什么(我也不知道
copy代码时间!#include<iostream> #include<cstring> #include<cstdio> using namespace std; __int128 f[10001]; void write(__int128 x) { if(x>9) write(x/10);//如果x>9的话就递归它的最高位,再往下依次输出 putchar(x%10+'0');//输出这个数的末尾/kk(+'0'是为了让它转成字符类型的 } int main() { int n,k; cin>>n>>k; f[0]=1;//初始化!让n为0时的方案数为1 for(int i=1;i<=k;i++)//枚举每一个物品 { for(int j=i;j<=n;j++)//必须大于i,否则买不了/kk { f[j]+=f[j-i];//那么这个方案数就是上面所推导的一坨 } } write(f[n]);//要用__int128否则会炸longlong(ull也好像不行 return 0; } -
0
#include <bits/stdc++.h> using namespace std; const int N=1010; __int128 f[N]; template<typename T> void qw(T x){ if(x<0) x=-x, putchar('-'); if(x>=10) qw(x/10); putchar(x%10+'0'); } int main(){ int n, K; scanf("%d%d", &n, &K); f[0]=1; for(int i=1; i<=K; i++){ for(int j=i; j<=n; j++){ f[j]+=f[j-i]; } } qw(f[n]); printf("\n"); return 0; }
- 1
信息
- ID
- 2307
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 7
- 标签
- 递交数
- 20
- 已通过
- 9
- 上传者