Poj--2184(DP,01背包,正负方向)
2014-12-12 16:16:03
思路:就是一个01背包,但是因为有负数的存在,所以要把起点设置为100 × 1000,dp数组也要开两倍(2 * 100 * 1000),然后DP方向也要注意下,正负方向相反。
1 /************************************************************************* 2 3 > File Name: 2184.cpp 4 > Author: Natureal 5 > Mail: 564374850@qq.com 6 > Created Time: Fri 12 Dec 2014 03:04:55 PM CST 7 ************************************************************************/ 8 9 #include <cstdio> 10 #include <cstring> 11 #include <cstdlib> 12 #include <cmath> 13 #include <vector> 14 #include <map> 15 #include <set> 16 #include <stack> 17 #include <queue> 18 #include <iostream> 19 #include <algorithm> 20 using namespace std; 21 #define lp (p << 1) 22 #define rp (p << 1|1) 23 #define getmid(l,r) (l + (r - l) / 2) 24 #define MP(a,b) make_pair(a,b) 25 typedef long long ll; 26 const int INF = 1 << 30; 27 const int maxn = 110; 28 29 int N,tmax,tmin,l,r; 30 int S[maxn],F[maxn]; 31 int dp[maxn * 2000]; 32 int st = 100 * 1000; 33 34 int main(){ 35 tmax = tmin = 0; 36 scanf("%d",&N); 37 for(int i = 1; i <= N; ++i){ 38 scanf("%d%d",&S[i],&F[i]); 39 if(S[i] > 0) tmax += S[i]; 40 else tmin += S[i]; 41 } 42 l = st + tmin; 43 r = st + tmax; 44 for(int i = l; i <= r; ++i) 45 dp[i] = -INF; 46 dp[st] = 0; 47 for(int i = 1; i <= N; ++i){ 48 if(S[i] > 0){ 49 for(int j = r; j >= l; --j) 50 if(j - S[i] >= l && j - S[i] <= r && dp[j - S[i]] != -INF) 51 dp[j] = max(dp[j],dp[j - S[i]] + F[i]); 52 } 53 else{ 54 for(int j = l; j <= r; ++j) 55 if(j - S[i] >= l && j - S[i] <= r && dp[j - S[i]] != -INF) 56 dp[j] = max(dp[j],dp[j - S[i]] + F[i]); 57 } 58 } 59 int ans = 0; 60 for(int j = st; j <= st + tmax; ++j){ 61 if(dp[j] < 0) continue; 62 ans = max(ans,j - st + dp[j]); 63 } 64 printf("%d\n",ans); 65 return 0; 66 }