1. 程式人生 > >HDU5890:Eighty seven(Bitset優化背包)

HDU5890:Eighty seven(Bitset優化背包)

void them move n-n ati else ann 提交 cor

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;
}

HDU5890:Eighty seven(Bitset優化背包)