hdu 5890 Eighty seven DP

来源:互联网 发布:c# vsa javascript 编辑:程序博客网 时间:2024/06/16 18:24

http://acm.hdu.edu.cn/showproblem.php?pid=5890
题意:

给n个数,选10个,看能否使得sum==87


然后q次询问,每次询问会从n个数里删掉 1-3个数,然后问 能否可以【选10个,看能否使得sum==87】..


L【i】【j】【k】【sum】 ,前j个数,不选第i个,选了k个数,和为sum

R【】【】【】【】【】 同样定义,

处理好这两个dp后,

每次询问,暴力for k 和 sum 这2维。


#include<bits/stdc++.h>using namespace std;const int maxn = 55;bool L[maxn][maxn][11][90],R[maxn][maxn][11][90];int a[maxn];int n;int main(){    //freopen("input.txt","r",stdin);    int tt;    scanf("%d",&tt);    while(tt--)    {        scanf("%d",&n);        for (int i=1; i<=n; i++)            scanf("%d",&a[i]);        memset(L,0,sizeof(L));        memset(R,0,sizeof(R));        L[0][0][0][0]=1;        for (int j=1; j<=n; j++)        {            for (int i=0; i<=j; i++)            {                for (int k=0; k<=10; k++)                {                    for (int sum=0; sum<=87; sum++)                    {                        if (i==0)                        {                            if (k<=j)                            {                                L[i][j][k][sum]=L[i][j][k][sum] | L[i][j-1][k][sum];                                if (k>=1 && sum-a[j]>=0)                                    L[i][j][k][sum]=L[i][j][k][sum] | L[i][j-1][k-1][sum-a[j]];                            }                        }                        else if (i<j)                        {                            if (k<j)                            {                                L[i][j][k][sum]=L[i][j][k][sum] | L[i][j-1][k][sum];                                if (k>=1 && sum-a[j]>=0)                                    L[i][j][k][sum]=L[i][j][k][sum] | L[i][j-1][k-1][sum-a[j]];                            }                        }                        else                        {                            if (k<j)                                L[i][j][k][sum]=L[i][j][k][sum] | L[0][j-1][k][sum];                        }                    }                }            }        }        R[n+1][n+1][0][0]=1;        for (int j=n; j>=1; j--)        {            for (int i=j; i<=n+1; i++)            {                for (int k=0; k<=10; k++)                {                    for (int sum=0; sum<=87; sum++)                    {                        if (i==n+1)                        {                            if (k<=n-j+1)                                {                                    R[i][j][k][sum]=R[i][j][k][sum] | R[i][j+1][k][sum];                                    if (k>=1 && sum-a[j]>=0)                                        R[i][j][k][sum]=R[i][j][k][sum] | R[i][j+1][k-1][sum-a[j]];                                }                        }                        else if (i>j)                        {                            if (k<n-j+1)                                {                                    R[i][j][k][sum]=R[i][j][k][sum] | R[i][j+1][k][sum];                                    if (k>=1 && sum-a[j]>=0)                                        R[i][j][k][sum]=R[i][j][k][sum] | R[i][j+1][k-1][sum-a[j]];                                }                        }                        else                        {                            if (k<n-j+1)                                R[i][j][k][sum]=R[i][j][k][sum] | R[n+1][j+1][k][sum];                        }                    }                }            }        }        int qq;        scanf("%d",&qq);        while (qq--)        {            int q[3];            scanf("%d%d%d",&q[0],&q[1],&q[2]);            sort(q,q+3);            int cun=unique(q,q+3)-q;            bool ok=0;            if (cun==1)            {                if (L[q[0]][n][10][87])                    ok=1;                else ok=0;            }            else if (cun==2)            {                for (int k=0; k<=10; k++)                    for (int sum=0; sum<=87; sum++)                    {                        if (L[q[0]][q[1]-1][k][sum] && R[n+1][q[1]+1][10-k][87-sum])                            ok=1;                    }            }            else            {                for (int k=0; k<=10; k++)                    for (int sum=0; sum<=87; sum++)                    {                        if (L[q[0]][q[1]-1][k][sum] && R[q[2]][q[1]+1][10-k][87-sum])                            ok=1;                    }            }            if (ok)                printf("Yes\n");            else printf("No\n");        }    }    return 0;}


0 0
原创粉丝点击