牛牛准备参加学校组织的春游, 出发前牛牛准备往背包里装入一些零食, 牛牛的背包容量为w。
牛牛家里一共有n袋零食, 第i袋零食体积为v[i]。
牛牛想知道在总体积不超过背包容量的情况下,他一共有多少种零食放法(总体积为0也算一种放法)。
输入包括两行
第一行为两个正整数n和w(1 <= n <= 30, 1 <= w <= 2 * 10^9),表示零食的数量和背包的容量。
第二行n个正整数v[i](0 <= v[i] <= 10^9),表示每袋零食的体积。
输出一个正整数, 表示牛牛一共有多少种零食放法。
3 10 1 2 4
8
三种零食总体积小于10,于是每种零食有放入和不放入两种情况,一共有2*2*2 = 8种情况。
import java.io.*; import java.util.*; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] params = br.readLine().split(" "); int n = Integer.parseInt(params[0]), w = Integer.parseInt(params[1]); params = br.readLine().split(" "); int[] v = new int[n]; long sum = 0; for(int i = 0; i < n; i++){ v[i] = Integer.parseInt(params[i]); sum += v[i]; } if(sum <= w){ System.out.println((int)Math.pow(2, n)); }else{ Map<Integer, Integer> dp = new HashMap<>(); dp.put(0, 1); System.out.println(dfs(v, w, 0, dp)); } } private static int dfs(int[] v, int rest, int index, Map<Integer, Integer> dp) { if(rest < 0){ return 0; } if(index == v.length){ if(!dp.containsKey(rest)){ dp.put(rest, 1); } }else{ if(!dp.containsKey(rest)){ int cnt = dfs(v, rest, index + 1, dp) + dfs(v, rest - v[index], index + 1, dp); dp.put(rest, cnt); } } return dp.get(rest); } }
import java.io.*; import java.util.*; public class Main { private static int count = 0; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] params = br.readLine().split(" "); int n = Integer.parseInt(params[0]), w = Integer.parseInt(params[1]); params = br.readLine().split(" "); int[] v = new int[n]; long sum = 0; for(int i = 0; i < n; i++){ v[i] = Integer.parseInt(params[i]); sum += v[i]; } if(sum <= w){ System.out.println((int)Math.pow(2, n)); }else{ dfs(v, w, 0); System.out.println(count); } } private static void dfs(int[] v, int rest, int index) { if(rest < 0){ return; // 背包容量不够了,本次尝试无效 } if(index == v.length){ count++; // 到头了,生成一种方案 }else{ dfs(v, rest, index + 1); // 不选index编号的零食 dfs(v, rest - v[index], index + 1); // 选index编号的零食 } } }
#include <iostream> #include <vector> using namespace std; class Solution { public: Solution(int n, int w, vector<long long> &v) :_n(n), _w(w), _ans(1) { _v.swap(v); } int func() { for (int i = 0; i < _v.size(); i++) { help(_v[i], i + 1); } return _ans; } private: int _n; int _w; int _ans; vector<long long> _v; private: void help(long long cw, int index) { if (cw > _w) { return; } if (cw <= _w) { _ans++; } for (int i = index; i < _v.size(); i++) { cw += _v[i]; help(cw, i + 1); cw -= _v[i]; } } }; int main() { int n, w; cin >> n >> w; vector<long long> v(n); for (int i = 0; i < n; i++) { cin >> v[i]; } Solution s(n, w, v); cout << s.func() << endl; return 0; }
#include <bits/stdc++.h>
typedef long long LL;
using namespace std;
int cnt,n;
LL w;
void walk(vector<LL>& co,int idx,LL curw)
{
if(curw>w)return;
if(idx>=n){cnt++;return;}
walk(co,idx+1,curw+co[idx]);
walk(co,idx+1,curw);
}
int main()
{
while(cin>>n>>w)
{
vector<LL> co(n);
LL sum=0;
for(int i=0;i<n;i++)
{
cin>>co[i];
sum+=co[i];
}
if(sum<=w){cout<<(1<<n)<<endl;continue;}
cnt=0;
walk(co,0,0);
cout<<cnt<<endl;
}
}
PYTHON,递归
line = raw_input()
n = int(line.split(' ')[0])
w = int(line.split(' ')[1])
line = raw_input()
v = []
for i in range(n):
v.append(int(line.strip().split(' ')[i]))
ans = 0
def main(v, w):
global ans
if sum(v) <= w:
print 2**(len(v))
else:
v.sort()
dfs(0, 0)
print ans
def dfs(su, loc):
global ans
if su > w:
return
if su <= w:
ans += 1
for i in range(loc, n):
dfs(su+v[i], i+1)
main(v, w)