您的位置:首页 > 其它

hdu 5890 Eighty seven DP

2016-09-17 18:16 148 查看
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]]
[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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: