题目
题目链接:http://poj.org/problem?id=3181
题目来源:《挑战》练习题
简要题意:用 1⋯K 面额的硬币有多少种方法构成 N 元。
数据范围:
1⩽N⩽1000;1⩽K⩽100
题解
很裸的完全背包,不过直接搞会爆LL。
java水过就行了。
之后发现极限数据就是二十几位吧,然后就顺手写了发c++的。
java代码
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
static BigInteger []a = new BigInteger[1005];
public static void main(String []args) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt(), k = cin.nextInt();
for (int i = 0; i <= n; i++) {
a[i] = BigInteger.ONE;
}
for (int i = 2; i <= k; i++) {
for (int j = i; j <= n; j++) {
a[j] = a[j].add(a[j-i]);
}
}
System.out.println(a[n]);
cin.close();
}
}
c++代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
// head
struct LLL {
static const LL MOD = 1e18;
LL a[2];
inline LLL operator +=(const LLL &o) {
a[0] += o.a[0];
a[1] += o.a[1];
if (a[0] >= MOD) a[1]++, a[0] -= MOD;
}
void wt() {
if (a[1] > 0) printf("%I64d%018I64d\n", a[1], a[0]);
else printf("%I64d\n", a[0]);
}
};
LLL dp[1005];
int main()
{
int n, k;
scanf("%d%d", &n, &k);
dp[0].a[0] = 1;
for (int i = 1; i <= k; i++) {
for (int j = i; j <= n; j++) {
dp[j] += dp[j-i];
}
}
dp[n].wt();
return 0;
}