POJ 2923 Relocation

来源:互联网 发布:网络维护培训课程 编辑:程序博客网 时间:2024/04/29 17:21

状态压缩。一开始思路不怎么清晰,写了个比较挫的代码,数组刚好是10导致递归到11时re,改正后超时。优化了下,把求所有可以转移的状态放到dp循环外面先处理出来。本来不怎么抱希望能过的,结果过了。。。

#include <cstdio>#include <algorithm>#include <cstring>#include <cstdlib>#include <iostream>#include <cmath>using namespace std;typedef long long LL;#define INF 1000000007#define N 1000int dp[20][1 << 11];int r1[1 << 11];int r2[1 << 11];int r[1 << 11];int w[20];int c1, c2, n;int main(){    int t;    int num = 1;    scanf("%d", &t);    while(t--){        scanf("%d%d%d", &n, &c1, &c2);        for(int i = 0; i < n; i++)            scanf("%d", &w[i]);        memset(dp, 0, sizeof(dp));        dp[0][0] = 1;        int ans = INF;        memset(r1, 0, sizeof(r1));        memset(r2, 0, sizeof(r2));        memset(r, 0, sizeof(r));        for(int k = 0; k < (1 << n); k++){            int sum = 0;            for(int l = 0; l < n; l++){                if((1 << l) & k){                    sum += w[l];                }            }            if(sum <= c1){                r1[k] = 1;            }            if(sum <= c2){                r2[k] = 1;            }        }        for(int k = 0; k < (1 << n); k++){            for(int l = 0; l < (1 << n); l++){                if(r1[k] && r2[l])r[k | l] = 1;            }        }        for(int i = 1; i <= n; i++){            for(int j = 0; j < (1 << n); j++){                if(!dp[i - 1][j])continue;                for(int k = 0; k < (1 << n); k++){                    if(r[k])dp[i][j | k] = 1;                }            }            if(dp[i][(1 << n) - 1]){ans = i; break;}        }        printf("Scenario #%d:\n%d\n\n", num++, ans);    }    return 0;}


0 0