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 N(N≤50)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(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 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; }