总结
1. 这种状态转移的题目不太好 debug, 写起来总觉得不对劲
2. 动规的初始化总能找到一些简练的初始化方法, 比如这道题, 可以选择 j>=0, dp[0] = 1, 或者对 vector 中的所有元素赋值 dp[s] = 1, 然后 j > 0
代码 TLE 了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 |
/* * source.cpp * * Created on: Apr 6, 2014 * Author: sangs */ #include <stdio.h> #include <iostream> #include <string> #include <vector> #include <memory.h> #include <algorithm> #include <math.h> using
namespace std; int
arr[100]; vector< int > state; int
dp[100100]; bool
cal( int
n, int
si, int
load1, int
load2) { int
sum = 0; bool
dp1[200]; memset (dp1, 0, sizeof (dp1)); dp1[0] = true ; for ( int
i = 0; i < n; i ++) { if (((1<<i) & si )== 0) continue ; sum += arr[i]; if (arr[i] > load1) continue ; for ( int
j = load1; j >= arr[i]; j -- ) { dp1[j] |= dp1[j-arr[i]]; } } int
sum1 = 0; for ( int
i = load1; i >= 0; i --) { if (dp1[i]) { sum1 = i; break ; } } if (sum-sum1 <= load2) return
true ; return
false ; } void
func1( int
n, int
load1, int
load2) { int
endState = (1<<n); for ( int
i = 1; i < endState; i++) { if (cal(n, i, load1, load2)) { state.push_back(i); } } } int
solve_dp( int
n) { memset (dp, 0x3f, sizeof (dp)); dp[0] = 0; for ( size_t
i = 0; i < state.size(); i ++) { for ( int
j = (1<<n)-1; j >= 0; j --) { dp[j|state[i]] = min(dp[j|state[i]], dp[j]+1); } } return
dp[(1<<n)-1]; } int
main() { freopen ( "input.txt" , "r" , stdin); int
cases; scanf ( "%d" , &cases); int
seq = 0; while (cases --) { seq ++; int
n, load1, load2; scanf ( "%d%d%d" , &n, &load1, &load2); for ( int
i = 0; i < n; i ++) scanf ( "%d" , arr+i); func1(n, load1, load2); int
res = solve_dp(n); printf ( "Scenario #%d:\n%d\n\n" , seq, res); } return
0; } |
POJ 2923 Relocation(状态压缩DP),布布扣,bubuko.com
原文:http://www.cnblogs.com/zhouzhuo/p/3649500.html