hdu5937 Equation

来源:互联网 发布:库房库存数据分析 编辑:程序博客网 时间:2024/06/02 00:49

题解其实网上有
突然有点感想
为什么可以用搜索或状压,因为方案数很有限,它要求每种方案不同就意味着搜索的次数也一定,所以现在就应该坚定往这方面想,找部分方案的贪心。这和上一题一样,都是先暴力,后面处理。

#include<bits/stdc++.h>using namespace std;#define sz(X) ((int)X.size())#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef long long ll;const int INF = 0x3f3f3f3f;const int N = 1e5+5;int num[15];int X[15], Y[15], Z[15];int ans, tmp;int ok(int x, int nu) {    if(nu == 0) return 1;    else if(X[x] == Y[x]) {        if(num[X[x]] >= 2*nu && num[Z[x]] >= nu) return 1;    }else if(num[X[x]] >= nu && num[Y[x]] >= nu && num[Z[x]] >= nu) return 1;    return 0;}int cal(){//  printf("%d: ",tmp); for(int i = 1; i <= 9; ++i) printf("%d ",num[i]);    int ret = 0;    int pre[10];    for(int i = 1; i <= 9; ++i) pre[i] = num[i];    for(int i = 2; i <= 8; ++i) {        int mi = min(2, min( num[1], min(num[i], num[i+1]) ) );        num[1] -= mi; num[i] -= mi; num[i+1] -= mi; ret += mi;        if(num[1] == 0) break;    }    for(int i = 1; i <= 9; ++i) num[i] = pre[i];    return ret;}void dfs(int x, int pr) {    if(pr) {        int tt = cal();        tmp += tt;        ans = max(tmp, ans);        tmp -= tt;    }    if(x > 13) return;    int ed;    if(x < 10) ed = 2; else ed = 1;    for(int i = 0; i <= ed; ++i) {        if(ok(x,i)) {            num[X[x]] -= i; num[Y[x]] -= i; num[Z[x]] -= i; tmp += i;            dfs(x+1, i);            num[X[x]] += i; num[Y[x]] += i; num[Z[x]] += i; tmp -= i;        }    }}int main(){    int cc = 0;    for(int i = 2; i <= 9; ++i)        for(int j = i+1; j <= 9; ++j) {            if(i+j <= 9) {                X[++cc] = i; Y[cc] = j; Z[cc] = i+j;            }        }    for(int i = 10; i <= 13; ++i) {        X[i] = i-9; Y[i] = i-9; Z[i] = Y[i]+X[i];    }    int _; scanf("%d",&_);    for(int cas=1; cas<=_; ++cas) {        for(int i = 1; i <= 9; ++i) scanf("%d",&num[i]);        ans = cal(); tmp = 0;        dfs(1, 0);        printf("Case #%d: %d\n",cas,ans);    }    return 0;}
0 0