UVa 10364

again, didn't work it out until I saw other's solution, yes
this is a memorized search plus using bitmask representing states problem
why memorized search but not bottom-up?
because it's again a tree-structure DAG, I think...
whenever it's a tree-structure DAG,  use top-down and it's much easier
also bitwise operations are included to transit state or calculate
state:
    dp[i][j] - if can reach state i while have formed j sticks
transition:
    when calc(i, j)==l, means state i can form j sticks
        we only advance j by 1
    else
        dp[i][j]|=dp[k][j], for all k are pre states of i, means if i is 1111, then k could be
        0111, 1011, 1101, 1110
/* UVas */
/*****************************************************************************/
int n, m, a, l;
int s[21];
int d[1<<20][4];
int calc(int state, int c) {
    int r=0;
    for (int i=0; i<m; i++) { 
        r+=(((1<<i)&state)>>i)*s[i];
    }
    return r-c*l;
}
int dfs(int state, int c) {
    int &r=d[state][c];
    int length=calc(state, c);
    if (length==l) {
        return dfs(state, c+1);
    } else if (c==4) {
        return 1;
    } else if (r!=-1) {
        return r;
    } else {
        r=0;
        for (int i=0; i<m&&!r; i++) {
            if (!(state&(1<<i))&&(length+s[i]<=l)) {
                r|=dfs(state|(1<<i), c);
            }
        }
        return r;
    }
}
int main(void) {
    cin>>n;
    while (n--) {
        cin>>m;
        a=0;
        for (int i=0; i<m; i++) {
            cin>>s[i];
            a+=s[i];
        }
        if (a%4) {
            cout<<"no"<<endl;
        } else {
            l=a/4;
            memset(d, -1, sizeof(d));
            dfs(0, 0)?cout<<"yes":cout<<"no";
            cout<<endl;
        }
    }
    return 0;
}
/*****************************************************************************/

No comments :

Post a Comment