题目:
有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出 最优选法的方案数。注意答案可能很大,请输出答案模 1e9+7的结果。
输入格式
第一行两个整数,N,V用空格隔开,分别表示物品数量和背包容积。
接下来有 N行,每行两个整数 vi,wi用空格隔开,分别表示第 i 件物品的体积和价值。
输出格式
输出一个整数,表示 方案数 模 1e9+7的结果。
数据范围
0<N,V≤1000
0<vi,wi≤1000
输入样例
4 5
1 2
2 4
3 4
4 6
输出样例:
2
多一个数组cnt记录最大价值的方案数
为什么很多题目都要模1e9+7:模一个大数和模一个质数可以减少冲突。
比如说如果所有的结果都是偶数…你模6就只可能出现0, 2, 4这三种情况…但模5还是可以出现2, 4, 1, 3这四(4=5-1)种情况的…
hash表如果是用取模的方法也要模一个大质数来减少冲突,出题人也会这样来 希望减少你“蒙对“的概率。
而模1e9+7又有一个很好的特点,就是相加不爆int,相乘不爆long long。
import java.util.*;
class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int V = sc.nextInt();
int[] volume = new int[N];
int[] value = new int[N];
for(int i = 0; i < N; i++){
volume[i] = sc.nextInt();
value[i] = sc.nextInt();
}
int[] dp = new int[V+1];
int[] cnt = new int[V+1];
Arrays.fill(cnt,1);
int mod = (int)1e9+7;
for(int i = 0; i < N; i++){
for(int j = V; j >= volume[i]; j--){
if(dp[j-volume[i]]+value[i] > dp[j]){
dp[j] = dp[j-volume[i]]+value[i];
cnt[j] = cnt[j-volume[i]]%mod;
}
else if(dp[j-volume[i]]+value[i]==dp[j]){
cnt[j] = (cnt[j]+cnt[j-volume[i]])%mod;
}
}
}
System.out.print(cnt[V]) ;
}
}