• 【HDU5890】Eighty seven


    题目大意:给定 N 个数,M 个询问,每次询问如果去掉三个数(可能相同),能否选择恰好 10 个数字,凑出 87 这个数。

    题解:骚操作。。
    集合凑数问题是一个很经典的模型,即:背包问题。
    先进行预处理,每次枚举三个位置,跑一遍背包,计算出删除这三个位置的数是否可以组合出 87 这个数字。查询的时候直接 (O(1)) 回答即可。
    但是发现预处理复杂度为 (O(5*50*50*50*50*10*100)),过不了这题。由于背包中每一位都是以布尔值,因此进行 bitset 优化,即:优化掉 100 这一维,复杂度处以 32,刚刚好卡过。。

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    
    
    int n,m,num[51];
    bitset<100> dp[11];
    bool valid[51][51][51];
    
    void make(int x,int y,int z){
    	for(int i=0;i<=10;i++)dp[i].reset();
    	dp[0][0]=1;
    	for(int i=1;i<=n;i++){
    		if(i==x||i==y||i==z||num[i]>87)continue;
    		for(int j=10;j;j--){
    			dp[j]|=dp[j-1]<<num[i];
    		}
    	}
    	if(dp[10][87])valid[x][y][z]=1;
    	else valid[x][y][z]=0;
    }
    int main(){
    	int T;scanf("%d",&T);
    	while(T--){
    		scanf("%d",&n);
    		for(int i=1;i<=n;i++)scanf("%d",&num[i]);
    		for(int i=1;i<=n;i++)
    			for(int j=i;j<=n;j++)
    				for(int k=j;k<=n;k++)
    					make(i,j,k);
    		scanf("%d",&m);
    		while(m--){
    			int x[3];
    			for(int i=0;i<3;i++)scanf("%d",&x[i]);
    			sort(x,x+3);
    			puts(valid[x[0]][x[1]][x[2]]?"Yes":"No");
    		}
    	}	
    	
    	return 0;
    }
    
  • 相关阅读:
    Python模块之logging
    Python模块之configparser
    python序列化模块 json&&pickle&&shelve
    Python模块之hashlib
    最短路之Floyd(多源)HDU 1874
    Python类知识学习时的部分问题
    第9章 Python文件操作目录
    第8章 Python类中常用的特殊变量和方法目录
    第7章 Python类型、类、协议目录
    第6章 Python中的动态可执行方法目录
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/11077988.html
Copyright © 2020-2023  润新知