传送门:POJ3181
题意:有1到k共k种数,每种数有无限个,问能组成n的不同方案有多少种。
思路:开始没想到要高精度,用了大白P63页的方法去做,wa一发,搜题解才发现这不就是个裸的完全背包么。。容量是n,有价值1-k的k种物品。因为题目没要求取模,所以要用到高精度,模拟大数加法可以做,不过dalao们都是将答案分成两部分,一部分计算高位,一部分计算低位,这样既能加快运算速度,写起来还简便,不过这样写的前提条件是最大的答案不超过36位,否则就算是用两个long long 也表示不了了。
代码:
#include<iostream>
#include<stdio.h>
#define ll long long
using namespace std;
typedef pair<int,int>P;
const int MAXN=100010;
const ll inf = 1e18;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
ll dp1[MAXN];//高位
ll dp2[MAXN];//低位
int main()
{
int N, K;
cin >> N >> K;
dp2[0] = 1;
for(int i = 1; i <= K; i++)
{
for(int j = i; j <= N; j++)
{
dp1[j] = dp1[j] + dp1[j - i] + (dp2[j] + dp2[j - i]) / inf;
dp2[j] = (dp2[j] + dp2[j - i]) % inf;
}
}
if(dp1[N])
printf("%lld%018lld", dp1[N], dp2[N]);
else
cout << dp2[N] << endl;
return 0;
}