POJ3181 Dollar Dayz 动态规划,多重背包

来源:互联网 发布:使用线程池的java实例 编辑:程序博客网 时间:2024/05/16 15:43

Description

Farmer John goes to Dollar Days at The Cow Store and discovers an unlimited number of tools on sale. During his first visit, the tools are selling variously for $1, $2, and $3. Farmer John has exactly $5 to spend. He can buy 5 tools at $1 each or 1 tool at $3 and an additional 1 tool at $2. Of course, there are other combinations for a total of 5 different ways FJ can spend all his money on tools. Here they are: 

        1 @ US$3 + 1 @ US$2        1 @ US$3 + 2 @ US$1        1 @ US$2 + 3 @ US$1        2 @ US$2 + 1 @ US$1        5 @ US$1
Write a program than will compute the number of ways FJ can spend N dollars (1 <= N <= 1000) at The Cow Store for tools on sale with a cost of $1..$K (1 <= K <= 100).

Input

A single line with two space-separated integers: N and K.

Output

A single line with a single integer that is the number of unique ways FJ can spend his money.

Sample Input

5 3

Sample Output

5
   题目大意是商店里有价值1-k的商品,现使用N 刀去购买这些商品(不找零钱也不赊账)有多少种购买法。
   这题应该算是多重背包问题了,设C(k,n)为商品最大价值为k时候组合成总价值为n的购买方法数,
C(k, n) = C(k - 1, n - 0 * k) + C(k - 1,n - 1 * k) +...+C(k - 1,n - [n / k] * k),到这里编码就可以AC了,不过这个公式还是可以继续优化的,就贴上没有优化过的代码吧。不过要注意的是,需要使用高精度运算,为了偷懒,直接使用了java里的BigInteger。
import java.math.*;import java.util.Scanner;import java.io.*;public class Main {public static void main(String[] args) throws Exception{// TODO Auto-generated method stubBigInteger [][]DD = new BigInteger[2][1001];int n, k; Scanner cin=new Scanner(System.in);         n=cin.nextInt();         k=cin.nextInt();     for (int i = 0; i <= n;i++){DD[1][i] = new BigInteger("1");}for (int i = 2; i <= k; i++){for (int c = 0; c < 1001; c++)DD[i & 1][c] =  new BigInteger("0");DD[i & 1][0] =  new BigInteger("1");;for (int j = 1; j <= n;j++){for (int h = 0; h <= j / i;h++){DD[i & 1][j] = DD[i & 1][j].add(DD[(i - 1) & 1][j - h * i]);}}}    System.out.println(DD[k & 1][n].toString());}}

0 0
原创粉丝点击