zoukankan      html  css  js  c++  java
  • 1.26 动归赛总结

    得分:

    t1 100pts

    t2 100pts

    t3 保林(爆零)

    rk#8(初二巨佬真的太强了)Dy Dy Ti 镪 仂


    t1 公交换乘

    /*一维动归简单不多说*/
    
    #include <bits/stdc++.h>
    #define rep(a,b,c) for(int a=b;a<=c;a++)
    #define INF 0x3f3f3f3f
    using namespace std;
    
    int a[15],dis,dp[300];
    
    int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    int main()
    {
        rep(i,1,10)
        	a[i]=read();
        	
        dis=read();
        
        memset(dp,127,sizeof(dp));
        dp[0]=0;
        
        rep(i,1,10)
        	rep(j,i,dis)
        	    dp[j]=min(dp[j],dp[j-i]+a[i]);
        
    	printf("%d",dp[dis]);
        return 0;
    }
    

    t2 数字矩形

    /*
    1.坑点还是有,代码里有注释
    2.思维难度不是很大,维护ans的时候卡了一下*/
    
    #include<bits/stdc++.h>
    #define rep(i,a,b) for(register int i=(a);i<=(b);i++)
    #define dwn(i,a,b) for(register int i=(a);i>=(b);i--)
    using namespace std;
     
    int n,m;
    int dp[110][510],w[110][510];
    
    int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
     
    int main()
    {
        n=read(),m=read();
        
        rep(i,1,n)
        	rep(j,1,m)
        		w[i][j]=read();
        		
    	rep(i,1,n)
        {
            rep(j,1,m)//向下
                dp[i][j]=dp[i-1][j]+w[i][j];
                
            dwn(j,m-1,1)//向左,要先维护出右边!  
                dp[i][j]=min(dp[i][j],dp[i][j+1]+w[i][j]);	
    			
    		rep(j,2,m)//向右,要从2开始!!j-1>=0  
                dp[i][j]=min(dp[i][j],dp[i][j-1]+w[i][j]);	
        }
        
        int ans=dp[n][m];
    	
    	dwn(j,m-1,1)
    		ans=min(ans,dp[n][j]);
    		    
    	printf("%d",ans);
        return 0;
    }
    

    t3 排列


    /*注意以下几点:
    1.读字符串我习惯从1开始读;
    
    2.把一个串里的每个数字存下来的技巧见******1*******;
    
    3.S&(1<<(j-1))表示S和第j-1位的数字是否相同(是否是1);
    S|(1<<(j-1))表示把S的第j-1位修改为1;
    
    4.(k*10+a[j])表示计算除法中的下一位;
    
    5.注意去重的问题,我这里是使用了标记数组;
    
    6.注意dp[0][0]=1;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
    but ouyangjz推荐的去重方式见下面的一个代码;
    */
    
    #include<bits/stdc++.h>
    #define rep(a,b,c) for(int a=b;a<=c;a++)
    #define N 11
    using namespace std;
    
    int T,mod,len;
    int a[N],cnt,dp[1<<N][1002];
    bool b[N];
    char s[N];
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
    	{
            memset(dp,0,sizeof(dp));
            
            scanf("%s%d",s+1,&mod);
            len=strlen(s+1);
    		cnt=0;
    		
            rep(i,1,len)
    			a[i]=s[i]-'0';//把所有数字存一下******1*******
            
    		dp[0][0]=1;  //赋初值
            
    		rep(S,0,(1<<len)-1) //S表示当前所选的状态集合
    		{
                memset(b,0,sizeof(b));  //注意清零
                rep(j,1,len)
    				if(!(S&(1<<(j-1)))&&!b[a[j]])//如果a[j]已经转移过就不能继续转移了,j表示遍历s中的各位数字。
    				{ 
                    	b[a[j]]=1;
                    	rep(k,0,mod-1) //k表示对mod取余后的数
                        dp[S|(1<<(j-1))][(k*10+a[j])%mod]+=dp[S][k];
                	}
            }
            printf("%d
    ",dp[(1<<len)-1][0]);
        }
        return 0;
    }
    

    贴一个ouyang的代码

    /*
    去重:用全排列去重
    */
    #include <cstdio>
    #include <cstring>
      
    char s[15];
    int l,dp[5000][1005],f[15];
      
    int main()
    {
       // freopen("perm.in","r",stdin);
       // freopen("perm.out","w",stdout);
        int t,maxn,ans,mod;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%s",s);
            l=strlen(s);
            scanf("%d",&mod);
            for(int i=0; i<l; i++)
                f[i]=s[i]-'0';
            maxn=1<<l;
            for(int i=0; i<maxn; i++)
                for(int j=0; j<mod; j++)
                    dp[i][j]=0;
            dp[0][0]=1;
            for(int i=0; i<maxn; i++)
                for(int k=0; k<mod; k++)
                    if(dp[i][k])
                    {
                        for(int j=0; j<l; j++)
                            if((i&(1<<j))==0)
                                dp[i|(1<<j)][(k*10+f[j])%mod]+=dp[i][k];
                              
                    }
            ans=dp[maxn-1][0];
            int x,r;
            for(int i=0; i<10; i++)
            {
                x=0;
                for(int j=0; j<l; j++)
                    if(f[j]==i)x++;
                r=1;
                for(int j=1; j<=x; j++)
                    r=r*j;
                ans=ans/r;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

    UPD:粘一个LRL大佬的板子

    我改了一点点……大佬代码的可读性就是要比我这种蒟蒻弱一点……

    #define ll long long
    #define rep(i,a,b) for(register int i=(a);i<=(b);++i)
    #include<bits/stdc++.h>
    using namespace std;
    const int N=5055;
    const int M=2055;
    const int inf=0x3f3f3f3f;
    
    char s[555];
    ll cnt[15],a[15],mod,f[N][1055],ans;
    
    ll jiecheng(ll x)
    {
        if(x==1||x==0)return 1;
        ll ret=1;
        rep(i,2,x)ret*=i;
        return ret;
    }
    
    int main()
    {
        int T;
    	scanf("%d",&T);
        while(T--)
    	{
            scanf("%s %lld",s,&mod);
            
            int len=strlen(s);
            
            memset(cnt,0,sizeof(cnt));
            
            rep(i,0,len-1)
    		{
                a[i]=s[i]^48;
                cnt[a[i]]++;
            }
            
            int maxs=(1<<len)-1; 
            
            rep(i,0,maxs)
                rep(j,0,mod-1)
                    f[i][j]=0;
                
            f[0][0]=1;
            
            rep(i,0,maxs)//注意递推顺序,先确定k可以避免超时就超时 
                rep(k,0,mod-1)
                    if(f[i][k])
                        rep(j,0,len-1)
                            if((i&(1<<j))==0)
                                f[i|(1<<j)][(k*10+a[j])%mod]+=f[i][k]; 
                        
            ans=f[maxs][0];
            
    		rep(i,0,9)
    			ans/=jiecheng(cnt[i]);
            
    		printf("%lld
    ",ans); 
        } 
        return 0;
    }
    
  • 相关阅读:
    SMR磁盘学习1
    练笔-字符串,向量和数组6
    练笔-字符串,向量和数组5
    练笔-字符串,向量和数组4
    练笔-字符串,向量和数组3
    练笔--字符串,向量和数组2
    Redis系列-存储篇hash主要操作函数小结
    Redis系列-存储篇string主要操作函数小结
    Redis系列-远程连接redis并给redis加锁
    Pjax的使用
  • 原文地址:https://www.cnblogs.com/sjsjsj-minus-Si/p/11635648.html
Copyright © 2011-2022 走看看