• 大二下学期第六周周报 (2019.4.7) Apare_xzc


    大二下学期第六周周报

    2019/4/7 xzc


    本周做的题有:


    1. 上周组队赛补题

    2. 蓝桥杯补题:
        RSA解密
        糖果

    3. 周赛:B,C,D,E(A是WF的A题,不想补了)
        C题蘑菇园

    4. 基础DP1三道水题:
        B.Ignatius and the Princess IV map水题
        I.最少拦截系统 (LIS的运用)
        M.Harry And Dig Machine 暴力DFS(twt用我HDU的号交了一发状压dp)

    5. 2019西北工业大学程序设计创新实践基地春季选拔赛(重现赛)
        D题:简单鸽巢原理+组合数
      (篇幅有点儿少,贴个代码吧)

    /*
    xzc201804040921157 提交的代码
    提交时间:2019-04-06 14:08:25 语言:C++ 代码长度:993 运行时间: 48 ms 占用内存:31712K 
    运行状态:答案正确
    */
    
    #include <bits/stdc++.h>
    #define For(i,a,b) for(register int i=(a);i<=(b);++i)
    #define Rep(i,a,b) for(register int i=(a);i>=(b);--i)
    #define Mst(a,b) memset(a,(b),sizeof(a))
    #define LL long long
    #define MP make_pair
    #define pb push_back
    using namespace std;
    const int maxn = 2e6+100;
    const int mod = 1e9+7;
    LL r[maxn];
    LL fac[maxn];
    LL fast_pow(LL a,LL b)
    {
        LL ans = 1;
        while(b)
        {
            if(b&1) ans = ans*a%mod;
            a = a*a%mod;
            b>>=1;   
        }
        return ans;
    }
    void init()
    {
        fac[0] = 1;
        r[0] = 1;
        For(i,1,2000000) fac[i] = fac[i-1]*i%mod;
        r[2000000] = fast_pow(fac[2000000],mod-2);
        Rep(i,1999999,1)
            r[i] = r[i+1]*(i+1)%mod;
             
    }
    LL C(int n,int m)
    {
        if(n<m||m<0) return 0;
        return fac[n]*r[m]%mod*r[n-m]%mod;
    }
     
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        int m,n;
        init();
        while(cin>>n>>m)
        {
            LL ans1 = C(m-1,n-1); //C(m-1,n-1)
            LL ans2 = C(n+m-1,n-1); //C(m-1,n+m-1)
            printf("%lld %lld
    ",ans1,ans2);   
        }
        return 0;
    }
    

    还进行了经典(简单)dp的复习(扫盲)


    经典dp问题

    1. 最长上升子序列: nlogn lower_bound dp[i]记录的是长度为i的子序列的末尾的最小值
    /*
    I-最少拦截系统
    Status: Accepted  Memory: 1444kB
    Length: 1240      Lang: G++
    Submitted: 2019-04-04 13:07:41
    */
    #include <bits/stdc++.h>
    #define Mst(a,b) memset(a,(b),sizeof(a))
    #define For(i,a,b) for(register int i=(a);i<=(b);++i)
    #define LL long long
    #define MP make_pair
    #define pb push_back
    using namespace std;
    const int maxn = 1e6 + 100;
    int a[maxn];
    int dp[maxn];
    int pos[maxn];
    /*
    这道题求最长非递减子序列的个数,有LIS性质:答案等于最长递增子序列的长度(LIS记录的是每个递减序列的结尾)
    可以在更新dp数组的同时顺便记录导弹拦截的方案
    pos[]记录a[i]在递推过程中在dp[]中的下标,便于还原路径(但这道题vector记录方案就已经知道LIS了) 	   
    */
    int main()
    {
    	//freopen("in.txt","r",stdin);
       	//freopen("out.txt","w",stdout);
    	int n;
    	while(scanf("%d",&n)!=EOF)
    	{
    		For(i,1,n) scanf("%d",a+i);
    		vector<int> v[n+1];
    		dp[1] = a[1];
    		pos[1] = 1;
    		int len = 1;
    		v[1].push_back(a[1]);
    		For(i,2,n)
    		{
    			if(a[i]>dp[len])
    			{
    				dp[++len] = a[i];
    				pos[i] = len;
    				v[len].push_back(a[i]);// record the path 
    			}
    			else
    			{
    				int m = lower_bound(dp+1,dp+len+1,a[i])-dp;
    				dp[m] = a[i];
    				v[m].push_back(a[i]); //record the path
    			}
    		}
    		printf("%d
    ",len);
    		//print the path
    		/*
    		For(i,1,len)
    		{
    			cout<<i<<": "; 
    			for(auto &t:v[i]) cout<<t<<" ";cout<<endl;
    		}
    		*/
    	}	
    	return 0;
    }
    
    1. 最大子段和 : O(n)
    //a[0] = 0
    for i in range (1,n):
        dp[i] = a[i] + max(0,dp[i-1)
        ans = max(ans,dp[i])
    
    1. 最大循环子段和: 最大的 和sum-最小的取max
    2. 最大公共子序列: dp O(n*m)
    dp[i][j] = max(dp[i-1][j],dp[i)[j-1],dp[i-1][j-1]+a[i]==b[j])  
    //应该是这样的吧,dp[i][j]代表a的前i位的和b的前j为最长公共子序列的长度
    
    
    1. 最大公共子串 : 后缀数组(nlogn) 去学一下?
    2. 最大子矩阵和 : O(n^3) 51Nod 1051
      预处理竖的前缀和,枚举up,down,宽度用最大子段和
    //author: xzc
    #include <bits/stdc++.h> 
    #define Mst(a,b) memset(a,(b),sizeof(a))
    #define For(i,a,b) for(register int i=(a);i<=(b);++i)
    #define LL long long
    #define MP make_pair
    #define pb push_back
    using namespace std;
    const int maxn = 510;
    LL a[maxn][maxn];
    LL s[maxn][maxn],res,ans;
    int main()
    {
    	int m,n;
    	while(scanf("%d%d",&n,&m)!=EOF)
    	{
    		For(i,0,500) s[0][i] = s[i][0] = 0;
    		For(i,1,m)
    			For(j,1,n)
    				scanf("%lld",&a[i][j]),
    				s[i][j] = a[i][j]+s[i-1][j];	
    		res = a[1][1];
    		For(up,1,m)
    		{
    			For(down,up,m)
    			{
    				ans = 0;
    				For(k,1,n)
    				{
    					ans = max(ans,0ll)+s[down][k]-s[up-1][k];
    					res = max(res,ans);
    				} 
    			}
    		}
    		printf("%lld
    ",res);
    	} 
    	return 0;
    }
    

  • 相关阅读:
    Irrlicht_0.1源码学习(3)—Irrlicht.cpp & include/Irrlicht.h
    Irrlicht_0.1源码学习(2)—引擎目录结构
    Irrlicht_0.1源码学习(1)—Welcome to the Irrlicht Engine
    Visual Studio 2013 编译时 "error LNK2026:模块对于 SAFESEH 映像是不安全的" 解决方案
    Windows平台下Lua环境的搭建
    系统调用与API
    前端学习技巧分享
    简单的bootstarp项目实例
    js显示表单的提交验证
    拷贝一张图片,从一个目录到另外一个目录下(PS:是拷贝是不是移动)
  • 原文地址:https://www.cnblogs.com/Apare-xzc/p/12243654.html
Copyright © 2020-2023  润新知