Live2d Test Env

HDU5890:Eighty seven(Bitset优化背包)

Mr. Fib is a mathematics teacher of a primary school. In the next lesson, he is planning to teach children how to add numbers up. Before the class, he will prepare NN cards with numbers. The number on the ii-th card is aiai. In class, each turn he will remove no more than 33 cards and let students choose any ten cards, the sum of the numbers on which is 8787. After each turn the removed cards will be put back to their position. Now, he wants to know if there is at least one solution of each turn. Can you help him?

InputThe first line of input contains an integer t (t5)t (t≤5), the number of test cases. tttest cases follow. 
For each test case, the first line consists an integer N(N50)N(N≤50). 
The second line contains NN non-negative integers a1,a2,...,aNa1,a2,...,aN. The ii-th number represents the number on the ii-th card. The third line consists an integer Q(Q100000)Q(Q≤100000). Each line of the next QQ lines contains three integers i,j,ki,j,k, representing Mr.Fib will remove the ii-th, jj-th, and kk-th cards in this turn. A question may degenerate while i=ji=j, i=ki=k or j=kj=k.
OutputFor each turn of each case, output 'Yes' if there exists at least one solution, otherwise output 'No'.Sample Input

1
12
1 2 3 4 5 6 7 8 9 42 21 22
10
1 2 3
3 4 5
2 3 2
10 10 10
10 11 11
10 1 1
1 2 10
1 11 12
1 10 10
11 11 12

Sample Output

No
No
No
Yes
No
Yes
No
No
Yes
Yes

题意:N个物品,分别有自己的值,Q个问题,每次问拿走第X个,第Y个和第Z个物品后,是否能在里面找10个物品,使其和为87。

思路:需要用Bitset优化背包。

感受:对青岛的题目早有耳闻,这次提交了很多次都来TLE,加了输入优化后还是TLE。说明问题不在输入上。

          最后Debug了很久,才发现,改了下面一点点就AC了,居然卡“逻辑运算”吗。

      if(ans[x[0]][x[1]][x[2]]==true) puts("Yes");
改为   if(ans[x[0]][x[1]][x[2]]) puts("Yes");

上面的代码改为下面的代码就AC了,而且依然是967ms,而时限猜1000ms。

(如果有幸去青岛赛区,一定要输入输出优化,一定要检查很多遍再提交)

#include<bitset>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
bool ans[55][55][55];
bitset<90>s[20];
int a[60],N;
int read()
{
    char c=getchar(); int res;
    while(c>'9'||c<'0') c=getchar();
    for(res=0;c>='0'&&c<='9';c=getchar()) res=(res<<3)+(res<<1)+c-'0';
    return res;
}
void solve(int x,int y,int z)
{
    for(int i=0;i<=11;i++) s[i].reset(); 
    s[0][0]=1;
    for(int i=1;i<=N;i++){
        if(i==x||i==y||i==z||a[i]>87) continue;
        for(int j=10;j>=1;j--) s[j]|=s[j-1]<<a[i];
    }
    if(s[10][87]==1) ans[x][y][z]=true;
    else ans[x][y][z]=false; 
}
int main()
{
    int T,Q;
    T=read();
    while(T--){
        scanf("%d",&N);
        for(int i=1;i<=N;i++)
            a[i]=read();
            
        for(int i=1;i<=N;i++)
         for(int j=i;j<=N;j++)
          for(int k=j;k<=N;k++)
               solve(i,j,k);
               
        Q=read();
        while(Q--){
            int x[3];
            x[0]=read(); x[1]=read(); x[2]=read();
            sort(x,x+3);
            if(ans[x[0]][x[1]][x[2]]) puts("Yes");
            else puts("No");
        }
    }
    return 0;
}

 

posted @ 2018-03-10 20:05  nimphy  阅读(597)  评论(0编辑  收藏  举报