【HDU 5890】Eighty seven(bitset+DP+优化)

来源:互联网 发布:2013日本进出口数据 编辑:程序博客网 时间:2024/06/11 09:55

【HDU 5890】Eighty seven(bitset+DP+优化)

题目大意:
n张纸牌,每张有分数。
q次询问,每次抽走三张牌,可能有重牌。
问剩下的牌能否拿出恰好十张加和出87

赛时想到ans[i][j][k]存 拿走编号i,j,k牌后的答案,这样如果某次询问之前问过,直接输出就好,组合得来不重复的询问大约2W,当时暴力DP,TLE的死死的……反正当时杭电也炸了……交着娱乐。。。

回来看到bitset,愣了。。怎么用bitsetDP啊……卧槽……用bitsetDP啊 !!!

开十个bitset,表示用了几张牌后的状态,大小开87,表示当前取i张牌能组成的分数。

转移就成了bit[i+1] |= bit[i]<

#include <iostream>#include <cmath>#include <vector>#include <cstdlib>#include <cstdio>#include <climits>#include <ctime>#include <cstring>#include <queue>#include <bitset>#include <stack>#include <list>#include <algorithm>#include <map>#include <cassert>#include <set>#define LL long long#define Pr pair<int,int>#define fread(ch) freopen(ch,"r",stdin)#define fwrite(ch) freopen(ch,"w",stdout)using namespace std;const int INF = 0x3f3f3f3f;const int mod = 1e9+7;const double eps = 1e-8;const int maxn = 112345;int ans[55][55][55];bitset <88> bit[11];int dp[12][89];LL num[55];int a,b,c,n;int got[11];int pre[11][87];bool cal(){//j    bool f = 1;//j//j    for(int i = 1; i <= 10; ++i)//j    {//j        if(i == a || i == b || i == c)//j        {//j            f = 0;//j            break;//j        }//j    }//j//j    if(f) return true;    memset(bit,0,sizeof(bit));    bit[0][0] = 1;    for(int i = 0; i < n; ++i)    {        if(i == a || i == b || i == c || num[i] > 87) continue;        for(int k = 9; k >= 0; --k)        {            bit[k+1] |= bit[k]<<num[i];        }    }    return bit[10][87];}bool init(){    memset(dp,0,sizeof(dp));    dp[0][0] = 1;    for(int i = 0; i < n; ++i)    {        if(i == a || i == b || i == c) continue;        for(int k = 9; k >= 0; --k)        {            for(int j = 87; j-num[i] >= 0; --j)            {                if(dp[k][j-num[i]])                 {                    if(!dp[k+1][j]) pre[k+1][j] = i;                    dp[k+1][j] = 1;                }            }        }        if(dp[10][87])        {            int x,y;            x = 10;            y = 87;            for(int i = 10; i > 0; --i)            {                got[i] = pre[x][y];                y -= num[pre[x][y]];                x--;            }            return true;        }    }    return false;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        memset(ans,-1,sizeof(ans));        scanf("%d",&n);        for(int i = 0; i < n; ++i) scanf("%lld",&num[i]);        int q;        scanf("%d",&q);        //bool f = init();        //for(int i = 1; i <= 10; ++i) printf("%d %lld\n",got[i],num[got[i]]);        while(q--)        {            scanf("%d%d%d",&a,&b,&c);            a--,b--,c--;            if(a > b) swap(a,b);            if(a > c) swap(a,c);            if(b > c) swap(b,c);            //if(!f)            //{            //    puts("NO");            //    continue;            //}            if(ans[a][b][c] == -1)            {                memset(dp,0,sizeof(dp));                ans[a][b][c] = cal();            }            if(ans[a][b][c] != -1)            {                puts(ans[a][b][c]? "Yes": "No");                continue;            }        }    }    return 0;}
0 0
原创粉丝点击