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:\n%d\n\n", seq, res);
}
return 0;
}

浙公网安备 33010602011771号