• T137226 彩虹海


    设目标体系$(n,a)$和答案体系$(m,b)$分别为集合$A$和集合$B$,那么我们可以猜想$Bsubseteq A$。

    我们可以先通过反证法验证下面两个结论:

    若$xin A$可以被其他$A$中的数表达出来,那么有$x otin B$。

    若$xin A$不能被其他$A$中的数表达出来,那么有$xin B$。

    然后再通过上述结论,使用反证法证明$Bsubseteq A$。具体就是取一个$x$,令$xin B$且$x otin A$,证明这样的$x$不存在。

    于是我们只需要找到$A$中能被表达出来的数并删去即可。

    具体来说,需要先将$a$排序,然后每次$forall xin[a_i,a_n]$,令$f_xleftarrow f_{x-a_i}$。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define IL inline
    #define RG register
    using namespace std;
    #define RI RG int
    #define RC RG char 
    const int N=100;
    const int M=25000;
    
        int T,n,a[N+3];
        bool f[M+3];
        
    IL void sol(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
            
        sort(a+1,a+n+1);
        memset(f,0,sizeof(f));
        
        f[0]=1;
        int ans=n;
        for(RI i=1;i<=n;i++){
            if(f[a[i]]){
                ans--;
                continue;
            }
            
            for(int j=a[i];j<=a[n];j++)
                f[j]|=f[j-a[i]];
                
        }
        printf("%d
    ",ans);
        
    }
        
    int main(){
        freopen("data.in","r",stdin);
        freopen("data.ans","w",stdout);
        
        scanf("%d",&T);
        while(T--)
            sol();
            
        return 0;
        
    }
    View Code
  • 相关阅读:
    redis总结
    java程序启动脚本
    mysql生成百万测试数据脚本
    java分布式锁的实现及在springboot中的应用
    mysql使用总结
    一个java实现代码(服务)编排的思路(未完)
    sentinel自定义统一限流降级处理
    shell学习
    oracle查看被锁的事务进程sql
    Sql查询两个时间段有重叠的记录
  • 原文地址:https://www.cnblogs.com/Hansue/p/13187634.html
Copyright © 2020-2023  润新知