题目
给定 V种货币(单位:元),每种货币使用的次数不限。
不同种类的货币,面值可能是相同的。
现在,要你用这 V种货币凑出 N元钱,请问共有多少种不同的凑法。
输入格式
第一行包含两个整数 V和 N。
接下来的若干行,将一共输入 V个整数,每个整数表示一种货币的面值。
输出格式
输出一个整数,表示所求总方案数。
数据范围
1≤V≤25
1≤N≤10000
答案保证在long long范围内。
- 输入样例:
3 10
1 2 5
- 输出样例:
10
题解
import java.util.Scanner;
/**
* @author akuya
* @create 2024-04-02-22:05
*/
public class Main {
static int V=26;
static int N=10010;
static int w[]=new int[26];
static int v;
static int n;
static long f[][]=new long[V][N];
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
v=scanner.nextInt();
n=scanner.nextInt();
for(int i=1;i<=v;i++){
w[i]=scanner.nextInt();
}
f[0][0]=1;
for(int i=1;i<=v;i++){
for(int j=0;j<=n;j++){
f[i][j]=f[i-1][j];
if(j-w[i]>=0)
f[i][j]+=f[i][j-w[i]];
}
}
System.out.println(f[v][n]);
}
}
思路
这道题是一道典型的背包问题,如果大家连背包问题都不了解的话得赶快去搜索点点资料扩充自己的知识点了,因为背包问题作为DP问题中较为基础且典型的题目,大家掌握之后才能对DP有更深入的理解,最其他题才能有最基本的思路。
这道题我们可以把总金额看成背包容量,货币面额等于物体总量。不限制物体数量只有重量,标准的完全背包问题,大家只需要将完全背包问题的代码改一改即可。
完全背包问题和各种背包问题可以改变代码从而优化空间,但那个是在太难理解,博主当初看y总视屏觉得懂了,但实际上过了一段时间就忘得一干二净写不出来。还是这种不节约空间但很容易看懂逻辑的代码适合我(我是菜鸡)。
大家如果想理解去看y总的算法基础课,博主没有那个实力讲解TWT。
这道题的基本逻辑还是“状态转移方程”和“集合”,比较特别的是完全背包问题的状态转移方程需要通过一定的数学计算优化,不然要超时,大家看下图即可。