HDU 5890 Eighty seven(bitset优化dp)
2016-09-21 11:17
405 查看
给你n个数字,询问,让你去掉3个数字,然后在剩下的里面取正好10个,能否取到87
可以想一下暴力预处理,C(50,3)也就2W多,然后dp[i][j][k]前i个数字选了j个和为k
复杂度是O(C(50,3)∗n∗10∗87),用bitset优化背包,能水过
bitset背包:
第二种方法时间复杂度小,考虑删除的3个数字,把这个数列分成了4段
然后对于中间那个数字,往两边看,pre[i][j][k][sum]表示前i个选了j个没选k和为sum
suf[i][j][k][sum]表示后i个,然后xjb维护一下
如果都选了,那么就是没选0和n+1,然后sum那一维也可以bitset优化
询问的时候枚举k和sum即可
预处理复杂度O(10∗n2),询问复杂度O(87∗10∗q)
代码:
可以想一下暴力预处理,C(50,3)也就2W多,然后dp[i][j][k]前i个数字选了j个和为k
复杂度是O(C(50,3)∗n∗10∗87),用bitset优化背包,能水过
bitset背包:
#include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <bitset> #include <cstring> #include <sstream> #include <cstdlib> #include <iostream> #include <algorithm> #pragma comment(linker,"/STACK:102400000,102400000") using namespace std; #define MAX 100005 #define MAXN 1000005 #define maxnode 15 #define sigma_size 30 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lrt rt<<1 #define rrt rt<<1|1 #define middle int m=(r+l)>>1 #define LL long long #define ull unsigned long long #define mem(x,v) memset(x,v,sizeof(x)) #define lowbit(x) (x&-x) #define pii pair<int,int> #define bits(a) __builtin_popcount(a) #define mk make_pair #define limit 10000 //const int prime = 999983; const int INF = 0x3f3f3f3f; const LL INFF = 0x3f3f; const double pi = acos(-1.0); const double inf = 1e18; const double eps = 1e-4; const LL mod = 1e9+7; const ull mx = 133333331; /*****************************************************/ inline void RI(int &x) { char c; while((c=getchar())<'0' || c>'9'); x=c-'0'; while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; } /*****************************************************/ int a[55],n; int b[55]; bitset<100> dp[15]; int ans[55][55][55]; void init(){ mem(ans,0); for(int i=1;i<=n;i++){ for(int j=i;j<=n;j++){ for(int k=j;k<=n;k++){ int tot=0; for(int h=1;h<=n;h++){ if(h!=i&&h!=j&&h!=k&&a[h]<=87) b[tot++]=a[h]; } for(int h=0;h<=10;h++) dp[h].reset(); dp[0][0]=1; for(int h=0;h<tot;h++){ for(int hh=10;hh;hh--) dp[hh]|=(dp[hh-1]<<b[h]); } if(dp[10][87]) ans[i][j][k]=1; } } } } int main(){ //freopen("in.txt","r",stdin); int t; cin>>t; while(t--){ cin>>n; for(int i=1;i<=n;i++) scanf("%d",&a[i]); init(); int q; cin>>q; while(q--){ int x[5]; scanf("%d%d%d",&x[0],&x[1],&x[2]); sort(x,x+3); if(ans[x[0]][x[1]][x[2]]) printf("Yes\n"); else printf("No\n"); } } return 0; }
第二种方法时间复杂度小,考虑删除的3个数字,把这个数列分成了4段
然后对于中间那个数字,往两边看,pre[i][j][k][sum]表示前i个选了j个没选k和为sum
suf[i][j][k][sum]表示后i个,然后xjb维护一下
如果都选了,那么就是没选0和n+1,然后sum那一维也可以bitset优化
询问的时候枚举k和sum即可
预处理复杂度O(10∗n2),询问复杂度O(87∗10∗q)
代码:
#include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <bitset> #include <cstring> #include <sstream> #include <cstdlib> #include <iostream> #include <algorithm> #pragma comment(linker,"/STACK:102400000,102400000") using namespace std; #define MAX 100005 #define MAXN 1000005 #define maxnode 15 #define sigma_size 30 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lrt rt<<1 #define rrt rt<<1|1 #define middle int m=(r+l)>>1 #define LL long long #define ull unsigned long long #define mem(x,v) memset(x,v,sizeof(x)) #define lowbit(x) (x&-x) #define pii pair<int,int> #define bits(a) __builtin_popcount(a) #define mk make_pair #define limit 10000 //const int prime = 999983; const int INF = 0x3f3f3f3f; const LL INFF = 0x3f3f; const double pi = acos(-1.0); const double inf = 1e18; const double eps = 1e-4; const LL mod = 1e9+7; const ull mx = 133333331; /*****************************************************/ inline void RI(int &x) { char c; while((c=getchar())<'0' || c>'9'); x=c-'0'; while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; } /*****************************************************/ int a[55],n; bitset<100> pre[55][15][55]; bitset<100> suf[55][15][55]; void init(){ for(int i=0;i<=n+1;i++){ for(int j=0;j<=10;j++){ for(int k=0;k<=n+1;k++){ pre[i][j][k].reset(); suf[i][j][k].reset(); } } } pre[0][0][0][0]=1; for(int i=1;i<=n;i++){ for(int j=10;j>=0;j--){ for(int k=0;k<=i;k++){ if(k==i){ for(int kk=0;kk<k;kk++) pre[i][j][k]|=pre[i-1][j][kk]; } else{ pre[i][j][k]|=pre[i-1][j][k]; if(j) pre[i][j][k]|=(pre[i-1][j-1][k]<<a[i]); } } } } suf[n+1][0][n+1][0]=1; for(int i=n;i>0;i--){ for(int j=10;j>=0;j--){ for(int k=n+1;k>=i;k--){ if(k==i){ for(int kk=n+1;kk>k;kk--) suf[i][j][k]|=suf[i+1][j][kk]; } else{ suf[i][j][k]|=suf[i+1][j][k]; if(j) suf[i][j][k]|=(suf[i+1][j-1][k]<<a[i]); } } } } } int main(){ //freopen("in.txt","r",stdin); int t; cin>>t; while(t--){ cin>>n; for(int i=1;i<=n;i++) scanf("%d",&a[i]); init(); int q; cin>>q; while(q--){ int x[5]; scanf("%d%d%d",&x[0],&x[1],&x[2]); sort(x,x+3); int flag=0; int q=unique(x,x+3)-x; if(q==1){ if(pre [10][x[0]][87]) flag=1; } else if(q==2){ for(int i=0;i<=10;i++){ for(int j=0;j<=87;j++){ if(pre[x[0]-1][i][0][j]&&suf[x[0]+1][10-i][x[1]][87-j]) flag=1; } } } else{ for(int i=0;i<=10;i++){ for(int j=0;j<=87;j++){ if(pre[x[1]-1][i][x[0]][j]&&suf[x[1]+1][10-i][x[2]][87-j]) flag=1; } } } if(flag) printf("Yes\n"); else printf("No\n"); } } return 0; }
相关文章推荐
- hdu_5890_Eighty seven(bitset优化DP)
- hdu 5890 Eighty seven 暴力+bitset优化背包
- hdu 5890 Eighty seven(背包+bitset)
- hdu 5890 Eighty seven 背包bitset
- [HDOJ5890]Eighty seven(暴力,dp,bitset)
- HDU 5890 Eighty seven ACM/ICPC 2015 Shenyang Online(DP+bitset优化)
- HDU 5745 La Vie en rose bitset优化dp
- HDU 5745 La Vie en rose(bitset优化dp)
- hdu 5890 01背包(bitset优化)
- dp+bitset优化______La Vie en rose( hdu 5745 2016多校第二场)
- 2015 Multi-University Training Contest 10 (hdu 5406-5416)数据结构+dp+矩阵快速幂+bitset优化拓扑排序+(dp&树状数组)
- HDU 5745 dp, bitset优化
- HDU 4374 One hundred layer(DP+单调队列优化)
- HDU 2993 MAX Average Problem(斜率优化DP)
- hdu 4258(斜率优化DP)
- hdu 4374 One hundred layer 单调队列优化dp
- HDU 2829 Lawrence(斜率优化DP)
- HDU 3507 Print Article【斜率优化dp】
- HDU 3507 Print Article(斜率DP优化)
- HDU 3415 Max Sum of Max-K-sub-sequence[单调队列优化dp]