EOJ 2113 WY II
EOJ 2113 http://acm.cs.ecnu.edu.cn/problem.php?problemid=2113
题意:背包问题,注意到N很小30,V很大10^7,故用dfs。
简单的dfs——O(2^N),这里需用剪枝。
引用背包九讲:
基本的剪枝方法不外乎可行性剪枝或最优性剪枝。
1.可行性剪枝即判断按照当前的搜索路径搜下去能否找到一个可行解,例如:若将剩下所有物品都放入背包仍然无法将背包充满(设题目要求必须将背包充满),则剪枝。
2.最优性剪枝即判断按照当前的搜索路径搜下去能否找到一个最优解,例如:若加上剩下所有物品的权值也无法得到比当前得到的最优解更优的解,则剪枝。
这题用2.最优性剪枝。
1 #include <iostream> 2 #include <stdio.h> 3 #include <string> 4 #include <algorithm> 5 #include <string.h> 6 #include <stdlib.h> 7 8 using namespace std; 9 10 int n, V; 11 int c[35], w[35]; 12 int ans; 13 14 int countWeight(int depth) 15 { 16 int sum = 0; 17 for(int i=depth; i<n; i++) 18 sum += w[i]; 19 return sum; 20 } 21 22 void dfs(int depth, int cost, int weight) 23 { 24 if(depth == n) 25 { 26 ans = max(ans, weight); 27 return ; 28 } 29 30 if(weight + countWeight(depth) <= ans) 31 return ; //最优性剪枝 32 33 dfs(depth+1, cost, weight); //不放 34 35 if(cost+c[depth] <= V) //放 36 dfs(depth+1, cost+c[depth], weight+w[depth]); 37 } 38 39 int main() 40 { 41 //freopen("testin.txt", "r", stdin); 42 //freopen("testout.txt", "w", stdout); 43 44 int t; 45 cin >> t; 46 while(t--) 47 { 48 cin >> n >> V; 49 for(int i=0; i<n; i++) 50 cin >> c[i] >> w[i]; 51 ans = 0; 52 dfs(0, 0, 0); 53 cout << ans << endl; 54 } 55 56 return 0; 57 }