题目描述
给定数组arr,设数组长度为n,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim,代表要找的钱数,求换钱的方法数有多少种。由于方法的种数比较大,所以要求输出对109+710^9+7109+7进行取模后的答案。
输入描述:
输出包括两行,第一行包括两个整数n(0≤n≤1000)(0 \leq n \leq 1000)(0≤n≤1000)和aim(0≤aim≤20000)(0 \leq aim \leq 20000)(0≤aim≤20000)。第二行包含n个整数,表示arr数组
输出描述:
输出一个整数,表示换钱的方法数对109+710^9+7109+7取模后的答案。
示例1
输入
4 15
5 10 25 1
输出
6
说明
5*3=15
10*1+5*1=15
10*1+1*5=15
1*10+5*1=15
5*2+1*5=15
1*15=15
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args)throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] info = br.readLine().trim().split(" ");
int len = Integer.parseInt(info[0]);
int aim = Integer.parseInt(info[1]);
String[] ss = br.readLine().trim().split(" ");
int[] arr = new int[len];
for(int i=0;i<len;i++){
arr[i] = Integer.parseInt(ss[i]);
}
int res = findNums(arr,aim);
System.out.println(res);
}
public static int findNums(int[] arr,int aim){
if(arr==null||arr.length==0||aim<=0) return 0;
return find(arr,0,aim);
}
public static int find(int[] arr,int index,int rest){
if(index==arr.length){
return rest==0?1:0;
}
int res = 0;
for(int i=0;i*arr[index]<=rest;i++){
res += find(arr,index+1,rest-i*arr[index]);
}
return res;
}
}
思路: 记住一些算过的值
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args)throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] info = br.readLine().trim().split(" ");
int len = Integer.parseInt(info[0]);
int aim = Integer.parseInt(info[1]);
String[] ss = br.readLine().trim().split(" ");
int[] arr = new int[len];
for(int i=0;i<len;i++){
arr[i] = Integer.parseInt(ss[i]);
}
int res = findNums(arr,aim);
System.out.println(res);
}
public static int findNums(int[] arr,int aim){
if(arr==null||arr.length==0||aim<=0) return 0;
int[][] map = new int[arr.length+1][aim+1];
return find(arr,0,aim,map);
}
public static int find(int[] arr,int index,int rest,int[][] map){
if(index==arr.length){
return rest==0?1:0;
}
long res = 0;
for(int i=0;i*arr[index]<=rest;i++){
int mapV = map[index+1][rest-i*arr[index]];
if(mapV!=0){
res += mapV==-1?0:mapV;
res %= 1000000007;
}else{
res += find(arr,index+1,rest-i*arr[index],map);
res %= 1000000007;
}
}
map[index][rest] =(int)( res==0?-1:res);
return (int)res;
}
}
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args)throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] info = br.readLine().trim().split(" ");
int len = Integer.parseInt(info[0]);
int aim = Integer.parseInt(info[1]);
String[] ss = br.readLine().trim().split(" ");
int[] arr = new int[len];
for(int i=0;i<len;i++){
arr[i] = Integer.parseInt(ss[i]);
}
int res = findNums(arr,aim);
System.out.println(res);
}
public static int findNums(int[] arr,int aim){
if(arr==null||arr.length==0||aim<=0) return 0;
if(aim==0) return 0;
int N = arr.length;
long[][] dp = new long[N+1][aim+1];
dp[N][0] = 1;
for(int i=N-1;i>=0;i--){
for(int j=0;j<=aim;j++){
if(j-arr[i]>=0){
dp[i][j] = dp[i][j-arr[i]]+dp[i+1][j];
}else{
dp[i][j] = dp[i+1][j];
}
dp[i][j] %= 1000000007;
}
}
return (int)dp[0][aim];
}
}
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args)throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] info = br.readLine().trim().split(" ");
int len = Integer.parseInt(info[0]);
int aim = Integer.parseInt(info[1]);
String[] ss = br.readLine().trim().split(" ");
int[] arr = new int[len];
for(int i=0;i<len;i++){
arr[i] = Integer.parseInt(ss[i]);
}
int res = findNums(arr,aim);
System.out.println(res);
}
public static int findNums(int[] arr,int aim){
if(arr==null||arr.length==0||aim<=0) return 0;
if(aim==0) return 0;
int N = arr.length;
long[] dp = new long[aim+1];
dp[0] = 1;
for(int i=N-1;i>=0;i--){
for(int j=0;j<=aim;j++){
if(j-arr[i]>=0){
dp[j] = dp[j-arr[i]]+dp[j];
}else{
dp[j] = dp[j];
}
dp[j] %= 1000000007;
}
}
return (int)dp[aim];
}
}