【题目描述】
dfs
dfs会超时
import java.io.*;
class Main{
static long ans;
static int V, N;
public static void dfs(int m, int left, int [] q){
//递归出口
if( left == 0){
ans++;
return;
}
//左分支选,条件:left - q[i] 限界函数
if( m < V &&left - q[m] >= 0 ) dfs(m, left -q[m], q);
//右分支 约束函数 不选
if( m < V) dfs(m + 1, left, q);
}
public static void main(String args[]) throws Exception{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String s []= bf.readLine().split(" ");
V = Integer.parseInt(s[0]);
N = Integer.parseInt(s[1]);
int [] q = new int[V];
String strArr [] = bf.readLine().split(" ");
for(int i = 0; i < V; i++ ) q[i] = Integer.parseInt(strArr[i]);
dfs(0, N, q);
System.out.println(ans);
}
}
动态规划
import java.io.*;
class Main{
static int V = 30, N = 10010;
public static void main(String args[]) throws Exception{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String s []= bf.readLine().split(" ");
int v = Integer.parseInt(s[0]);
int n = Integer.parseInt(s[1]);
int [] q = new int[V];
if( v != 25 ){
String strArr[] = bf.readLine().split(" ");
for(int i = 1; i <= v; i++) {
q[i] = Integer.parseInt(strArr[i - 1]);
}
}
else
//注意数据不太规范 最后一个是按行输入
for(int i = 1; i <= v; i++) {
q[i] = Integer.parseInt(bf.readLine());
}
//dp[i][j] 表示前i种货币凑成j元的方案数目
long dp[][] = new long[V][N];
//递推式:dp[i][j] = dp[i - 1][j] + dp[i - 1][ j - q[i]*k] ( k = 1,2 ……j/q[i])
//0种货币凑成0元的方案数为1
dp[0][0] = 1;
for(int i = 1; i <= v; i++){
for(int j = 0; j <= n; j++){
for( int k =0; k * q[i] <= j; k++)
dp[i][j] += dp[i - 1][j - q[i] * k];
}
}
/*
for(int i = 1; i <= V; i++){
for(int j = 1; j <= N; j++){
System.out.print(dp[i][j]+" ");
}
System.out.println();
}*/
System.out.println(dp[v][n]);
return ;
}
}