HDU5890:Eighty seven(Bitset優化背包)
InputThe first line of input contains an integer t (t≤5)t (t≤5), the number of test cases. tttest cases follow.
For each test case, the first line consists an integer
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(Q≤100000)Q(Q≤100000). Each line of the next QQ lines contains three integers i,j,ki,j,k, representing Mr.Fib will remove the
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優化背包)