hdu 5890 bitset+背包思想
2016-09-22 20:35
417 查看
链接:戳这里
Eighty seven
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)
Problem Description
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 N cards with numbers. The number on the i-th card is ai. In class, each turn he will remove no
more than 3 cards and let students choose any ten cards, the sum of the numbers on which is 87. 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?
Input
The first line of input contains an integer t (t≤5), the number of test cases. t test cases follow.
For each test case, the first line consists an integer N(N≤50).
The second line contains N non-negative integers a1,a2,...,aN. The i-th number represents the number on the i-th card. The third line consists an integer Q(Q≤100000). Each line of the next Q lines contains three integers i,j,k, representing Mr.Fib will remove
the i-th, j-th, and k-th cards in this turn. A question may degenerate while i=j, i=k or j=k.
Output
For 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个询问i,j,k,每次要求去掉1~3个数,问剩下的数是否存在选出10个数的总和为87
思路:
1:n=50 所以询问最多只有50*50*50,可以预处理出答案然后O(1)输出
2:对于每对i,j,k,去掉这个几个数后,对剩下的数01背包思想处理
问题抽象为:从n-3个物品中取出10个数使得总和为87
dp[i][j]表示取i个数是否能达到总和为j的状态 每个数取或不取(2^10)+一些剪枝(但是这样会T
3:考虑bitset<100> b[11]
b[i][j]表示当前存在i个数且总和为j的情况用bitset统计好了
b[i] |= b[i-1]<<a[j] 表示b[i-1]这个集合里面的所有的出现的数向右移a[j]个位置(其实就是理解为每个数加a[j]的操作),取抑或是a[j]这个数不取的情况
看一个bitset的用法
当前b[0][2]=1 b[0][5]=1
b[0]<<2 bitset[0]里面的所有数出现的位置向右移两个位置
0 1 2 3 4 5 6 7 8 9 10
0 0 1 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 1 0 0 0
代码:
Eighty seven
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)
Problem Description
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 N cards with numbers. The number on the i-th card is ai. In class, each turn he will remove no
more than 3 cards and let students choose any ten cards, the sum of the numbers on which is 87. 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?
Input
The first line of input contains an integer t (t≤5), the number of test cases. t test cases follow.
For each test case, the first line consists an integer N(N≤50).
The second line contains N non-negative integers a1,a2,...,aN. The i-th number represents the number on the i-th card. The third line consists an integer Q(Q≤100000). Each line of the next Q lines contains three integers i,j,k, representing Mr.Fib will remove
the i-th, j-th, and k-th cards in this turn. A question may degenerate while i=j, i=k or j=k.
Output
For 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个询问i,j,k,每次要求去掉1~3个数,问剩下的数是否存在选出10个数的总和为87
思路:
1:n=50 所以询问最多只有50*50*50,可以预处理出答案然后O(1)输出
2:对于每对i,j,k,去掉这个几个数后,对剩下的数01背包思想处理
问题抽象为:从n-3个物品中取出10个数使得总和为87
dp[i][j]表示取i个数是否能达到总和为j的状态 每个数取或不取(2^10)+一些剪枝(但是这样会T
3:考虑bitset<100> b[11]
b[i][j]表示当前存在i个数且总和为j的情况用bitset统计好了
b[i] |= b[i-1]<<a[j] 表示b[i-1]这个集合里面的所有的出现的数向右移a[j]个位置(其实就是理解为每个数加a[j]的操作),取抑或是a[j]这个数不取的情况
看一个bitset的用法
当前b[0][2]=1 b[0][5]=1
b[0]<<2 bitset[0]里面的所有数出现的位置向右移两个位置
0 1 2 3 4 5 6 7 8 9 10
0 0 1 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 1 0 0 0
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<list> #include<stack> #include<iomanip> #include<cmath> #include<bitset> #define mst(ss,b) memset((ss),(b),sizeof(ss)) ///#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; typedef long double ld; #define INF (1ll<<60)-1 #define Max 1e9 using namespace std; int f[55][55][55]; int a[55]; int n,q; bitset <100> b[11]; bool check(int i,int j,int k){ for(int l=0;l<=10;l++) b[l].reset(); b[0][0]=1; for(int l=1;l<=n;l++){ if(l!=i && l!=j && l!=k && a[l]<=87){ for(int o=10;o>=1;o--){ b[o]|=b[o-1]<<a[l]; } } } if(b[10][87]) return true; return false; } int c[5]; int main(){ /*bitset<10> B[10]; B[0][5]=1; B[0][2]=1; B[0]<<2; cout<<B[0]<<endl;*/ int T; scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); mst(f,0); for(int i=1;i<=n;i++){ for(int j=i;j<=n;j++){ for(int k=j;k<=n;k++){ if(check(i,j,k)) f[i][j][k]=1; else f[i][j][k]=0; } } } scanf("%d",&q); while(q--){ scanf("%d%d%d",&c[1],&c[2],&c[3]); sort(c+1,c+4); if(f[c[1]][c[2]][c[3]]) printf("Yes\n"); else printf("No\n"); } } return 0; }
相关文章推荐
- hdu 5890 Eighty seven 背包bitset
- hdu 5890 Eighty seven 暴力+bitset优化背包
- hdu 5890 Eighty seven(背包+bitset)
- hdu 6140 bitset+背包
- 简单DP 01 背包 饭卡HDU 2546 ( 饭卡 ) 不知道算不算是稍稍加了点贪心的思想~
- HDU 3446 有贪心思想的01背包
- hdu_5890_Eighty seven(bitset优化DP)
- hdu 5890 dp+bitset+输入挂
- HDU2191 多重背包(二进制思想)
- BestCoder Round #82 (div.1) 1002 HDU 5677 dp-类似多重背包的思想
- hdu 3008 简单dp(背包的思想)
- Combinatorics——HDUOJ 2110 - Crisis of HDU(母函数 / 多重背包思想)
- HDU 5313 bitset优化背包
- HDU 5890 Eighty seven(bitset优化dp)
- HDU 5890 Eighty seven ACM/ICPC 2015 Shenyang Online(DP+bitset优化)
- hdu 6140 Hybrid Crystals 阅读题 OR bitset 优化01背包
- hdu 5890 01背包(bitset优化)
- hdu 3732 Ahui Writes Word(多重背包的二进制思想优化)
- HDU 3466 【DP入门之01背包】
- HDU 1114 (dp 完全背包)