POJ 2923 Relocation(状态压缩DP)
总结
1. 这种状态转移的题目不太好 debug, 写起来总觉得不对劲
2. 动规的初始化总能找到一些简练的初始化方法, 比如这道题, 可以选择 j>=0, dp[0] = 1, 或者对 vector 中的所有元素赋值 dp[s] = 1, 然后 j > 0
代码 TLE 了
/* * 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: %d ", seq, res); } return 0; }