zoukankan      html  css  js  c++  java
  • 5.26 模拟赛

    5.26模拟赛

    DP专题

    A 货币系统

    NOIP2018原题 完全背包裸题

    码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<queue>
    #include<deque>
    #include<set>
    #include<stack>
    #include<bitset>
    #include<cstring>
    #define ll long long
    #define max(a,b) ((a>b)?a:b)
    #define min(a,b) ((a<b)?a:b)
    #define re register
    using namespace std;
    const int INF=0x3f3f3f3f,N=110,M=25010;
    
    inline int read(){
    	int x=0,y=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') y=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    	return x*y;
    }
    
    int t,n,a[N],f[M],maxx=0,ans=0;
    
    int main(){
    
    	// freopen("money.in","r",stdin);
    	// freopen("money.ans","w",stdout);
    	
    	t=read();
    	while(t--){
    		n=read();
    		ans=n;
    		memset(f,-INF,sizeof f);
    		maxx=0;
    		for(int i=1;i<=n;i++) a[i]=read(),maxx=max(maxx,a[i]),f[a[i]]=1;
    		sort(a+1,a+1+n);
    		for(int i=1;i<=n;i++){
    			for(int j=a[i];j<=maxx;j++){
    				int o=f[j];
    				f[j]=max(f[j],f[j-a[i]]+1);
    				
    			}
    		}
    		for(int i=1;i<=n;i++) if(f[a[i]]>1) ans--;
    		printf("%d
    ",ans);
    	}
    	
    	
    	// fclose(stdin);
    	// fclose(stdout);
    
        return 0;
    }
    
    
    

    B happiness

    不可做

    题意:有两辆有体积的车,同时来回,有一些物品有体积,问最少走多少趟能把所有物品转移

    听说可以用状压,但是我不会,等dalao来教,我只会二分答案用dfs判断(其实二不二分对复杂度也没啥影响,n太小了

    码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<queue>
    #include<deque>
    #include<set>
    #include<stack>
    #include<bitset>
    #include<cstring>
    #define ll long long
    #define max(a,b) ((a>b)?a:b)
    #define min(a,b) ((a<b)?a:b)
    using namespace std;
    const int INF=0x3f3f3f3f,N=110,S=1100;
    
    int t;
    
    inline int read(){
        int x=0,y=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') y=-1;c=getchar();}
        while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
        return x*y;
    }
    
    namespace work{
        int n,c1,c2,a[N],c[2*N],flag=0;
        void clear(){
            n=0,c1=0,c2=0;
            flag=0;
            memset(a,0,sizeof a);
        }
        void readin(){
            n=read();
            int c,b;
            c=read();
            b=read();
            c1=min(c,b);
            c2=max(c,b);
            for(int i=1;i<=n;i++) cin>>a[i];
            sort(a+1,a+1+n);
        }
    
        void dfs(int x,int cnt){
            if(!x){flag=1;return;}
            for(int i=1;i<=cnt*2&&!flag;i++){
                if(c[i]>=a[x]) c[i]-=a[x],dfs(x-1,cnt),c[i]+=a[x];
            }
        }
    
        bool check(int i){
            flag=0;
            for(int j=1;j<=i;j++) c[j]=c1;
            for(int j=i+1;j<=2*i;j++) c[j]=c2;
            dfs(n,i);
            if(flag){
                return 1;
            }
            return 0;
        }
    
        void sswork(int k){
            int l=1,r=n;
            while(l<r){
                int mid=(l+r)>>1;
                if(check(mid)) r=mid;
                else l=mid+1;
            }
            printf("Scenario #%d:
    %d
    
    ",k,l);
        }
        
    }
    
    int main(){
    
        t=read();
        int k=1;
        while(t--){
            work::clear();
            work::readin();
            work::sswork(k++);
        }
        
        return 0;
    }
    

    C 宝藏

    题意:给个树,边有边权,点有点权,每次经过一条边贡献是(-w),第一次经过一个点贡献是(val),问从每个节点出发的最大贡献是多少

    明显的换根DP,但是连根节点的DP都不会,考场上推柿子的时候考虑了三种情况,一种是从待更新的子树走到已更新的子树里,一种是从已更新的子树走到待更新的子树里,一种是只走待更新的子树,期望50,但是读取到20,考完了一想,只用记录从根节点走到待更新的子树里考虑回不回来就可以了,还简单,菜死了

    抄的std不知道啥意思

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<queue>
    #include<deque>
    #include<set>
    #include<stack>
    #include<bitset>
    #include<cstring>
    #define ll long long
    #define max(a,b) ((a>b)?a:b)
    #define min(a,b) ((a<b)?a:b)
    using namespace std;
    const int INF=0x3f3f3f3f,N=3000100;
    
    inline int read(){
        int x=0,y=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') y=-1;c=getchar();}
        while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
        return x*y;
    }
    
    int e[N],ne[N],h[N],w[N],idx=2;
    int f1[N],v[N],pos[N],f2[N],f3[N],f4[N];
    int n;
    
    void add(int a,int b,int c){
        e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
    }
    
    void dfs(int x,int fa){
        f1[x]=f2[x]=v[x];
        for(int i=h[x];~i;i=ne[i]){
            int j=e[i];
            if(j==fa) continue;
            dfs(j,x);
            f1[x]+=max(f1[j]-(w[i]<<1),0);
        }
        for(int i=h[x];~i;i=ne[i]){
            int j=e[i];
            if(f2[j]-w[i]>0&&j!=fa){
                int tmp=max(f1[j]-(w[i]<<1),0);
                int s=f1[x]-tmp+f2[j]-w[i];
                if(s>f2[x]){
                    f3[x]=f2[x];
                    f2[x]=s;
                    pos[x]=j;
                }else f3[x]=max(f3[x],s);
            }
        }
    }
    
    void dfsexroot(int x,int u,int val){
        int j=e[u^1];
        int t=max(f1[j]-(w[u]<<1),0);
        int s=f1[x]+val-w[u];
        f1[x]+=t,f2[x]+=t;
        if(s>f2[x]){
            f3[x]=f2[x];
            f2[x]=s;
            pos[x]=j;
        }else f3[x]=max(f3[x],s);
        for(int i=h[x];~i;i=ne[i]){
            if(i!=(u^1)){
                int k=e[i];
                int tmp=max(f1[k]-(w[i]<<1),0);
                f1[x]-=tmp;
                dfsexroot(k,i,(pos[x]==k?f3[x]:f2[x])-tmp);
                f1[x]+=tmp;
            }
        }
    }
    
    int main(){
    
        memset(h,-1,sizeof h);
    
        n=read();
        for(int i=1;i<n;i++){
            int a,b,c;
            a=read(),b=read(),c=read();
            add(a,b,c);
            add(b,a,c);
        }
    
        for(int i=1;i<=n;i++) v[i]=read();
    
        dfs(1,0);
    
        dfsexroot(1,0,0);
        
        for(int i=1;i<=n;i++) printf("%d
    ",f2[i]);
        return 0;
    }
    
  • 相关阅读:
    Javascript学习中比较核心的知识(持续更新)
    深入理解Builder模式(转载)
    Git 对文件进行批量rm操作
    Android 记录代码执行时间
    Git已跟踪文件的忽略方法
    Linux shell command line process(命令行处理流程)
    线程 方面笔记01
    c#中索引器
    sql记录
    颜色的处理
  • 原文地址:https://www.cnblogs.com/wsyunine/p/14824020.html
Copyright © 2011-2022 走看看