zoukankan      html  css  js  c++  java
  • 2017-01-20_dp测试

    题目:http://files.cnblogs.com/files/shenben/2017-01-20problems.pdf

    数据包(含解题报告):http://files.cnblogs.com/files/shenben/2017-01-20_%E6%B5%8B%E8%AF%95%E5%8C%85.zip

    plane

    /*
    f[nowx][nowy]=sigma(f[tox][toy]); 
    k=0:ans=sigma(f[nowx][nowy])
    以上动态转移显然
    全部数据要+ 二项式定理:bilibala…… 
    //数学弱,日后再推吧 
    */
    #include<cstdio>
    #define O3 __attribute__((optimize("O3")))
    #define IN inline
    using namespace std;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int N=310,M=25,p=12345,inf=0x3f3f3f3f;
    const int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
    int n,m,k,c[M][M],a[N][N],dp[N][N][M],t[M],ans[M];
    bool vis[N][N];
    O3 IN void dfs(int nowx,int nowy){
        vis[nowx][nowy]=1;
        for(int d=0;d<4;d++){
            int tox=nowx+dx[d],toy=nowy+dy[d];
            if(a[nowx][nowy]>a[tox][toy]){
                if(!vis[tox][toy]) dfs(tox,toy);
                t[0]=dp[tox][toy][0]+1;
                for(int i=1;i<=k;i++){
                    t[i]=dp[tox][toy][i];
                    for(int j=1;j<=i;j++){
                        t[i]+=((j&1)?1:-1)*c[i][j]*t[i-j];
                        t[i]%=p;
                    }
                }
                for(int i=0;i<=k;i++){
                    dp[nowx][nowy][i]+=t[i];
                    dp[nowx][nowy][i]%=p;
                }
            }
        }
    }
    #define name "plane"
    int main(){
        freopen(name".in","r",stdin);
        freopen(name".out","w",stdout);
        n=read();m=read();k=read();
        for(int i=0;i<=n+1;i++) a[i][0]=a[i][m+1]=inf;    
        for(int i=1;i<=m;i++) a[0][i]=a[n+1][i]=inf;    
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                a[i][j]=read();
            }
        }
        for(int i=0;i<=k;i++){
            c[i][0]=1;
            for(int j=1;j<=i;j++){
                c[i][j]=c[i-1][j]+c[i-1][j-1];
                c[i][j]%=p;
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(!vis[i][j]) dfs(i,j);
                for(int t=0;t<=k;t++){
                    ans[t]+=dp[i][j][t];
                    ans[t]%=p;
                }
            }
        }
        for(int i=0;i<=k;i++) if(ans[i]<0) ans[i]+=p;
        for(int i=0;i<=k;i++)  printf("%d
    ",ans[i]);
        fclose(stdin);fclose(stdout);
        return 0; 
    }

    knapsack

    /*
    离线预处理:多重背包正扫一遍,反扫一遍 
    ans=max(f[k1][j]+f_rev[k1+2][t1-j]){0<=j<=t1} 
    attention:
        习惯了一维的二进制拆分,二位的多重背包居然不会了~~ 
    */
    #include<cstdio>
    #include<iostream>
    using namespace std;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int N=1005;
    int n,m,v[N],w[N],c[N],f[N][N],f_rev[N][N];
    void pre_deal(){
        for(int i=1,tmp;i<=n;i++){
            tmp=c[i];
            for(int j=1;j<=1000;j++) f[i][j]=f[i-1][j];
            for(int j=1;tmp!=0;j<<=1){
                j=min(j,tmp);
                tmp-=j;
                for(int k=1000;k>=j*v[i];k--){
                    f[i][k]=max(f[i][k],f[i][k-j*v[i]]+j*w[i]);
                }
            }
        }
        for(int i=n,tmp;i>=1;i--){
            tmp=c[i];
            for(int j=1;j<=1000;j++) f_rev[i][j]=f_rev[i+1][j];
            for(int j=1;tmp!=0;j<<=1){
                j=min(j,tmp);
                tmp-=j;
                for(int k=1000;k>=j*v[i];k--){
                    f_rev[i][k]=max(f_rev[i][k],f_rev[i][k-j*v[i]]+j*w[i]);
                }
            }
        }
    }
    #define name "knapsack"
    int main(){
        freopen(name".in","r",stdin);
        freopen(name".out","w",stdout);
        n=read();
        for(int i=1;i<=n;i++) v[i]=read(),w[i]=read(),c[i]=read();
        pre_deal();
        m=read();
        for(int k1,t1,ans;m--;){
            k1=read();t1=read();ans=0;
            for(int j=0;j<=t1;j++) ans=max(ans,f[k1][j]+f_rev[k1+2][t1-j]);
            printf("%d
    ",ans);
        }
        fclose(stdin);fclose(stdout);
        return 0;
    }

    remainder

    //思路很好懂,然而还要套二项式,~~ 
    #include<cstdio>
    #include<iostream>
    using namespace std;
    typedef long long ll;
    const ll N=305,mod=905229641;
    ll n,m,ans,sum,tmp,f[N][N*N/2];//f(i,j)=长为i,余数和为j
    #define name "remainder"
    int main(){
        freopen(name".in","r",stdin);
        freopen(name".out","w",stdout);
        cin>>n>>m;
        f[0][0]=1;
        for(int k=0;k<m;k++){
            for(int i=k;i>=0;i--){
                for(int j=k*(k-1)/2;j>=0;j--){
                    f[i+1][j+k]+=f[i][j];
                    f[i+1][j+k]%=mod;
                }
            }
        }
        for(int i=0;i<=m*(m-1)/2;i++){
            if((n-i)%m) continue;
            for(int j=1;j<=m;j++){
                tmp=(n-i)/m+j-1;
                tmp%=mod;
                sum=1;
                for(int k=1;k<j;k++){//C(n-tot+x-1,x-1)
                    sum*=tmp;
                    sum%=mod;
                    tmp--;
                }
                sum*=j*f[j][i]%mod;
                sum%=mod;
                ans+=sum;
                ans%=mod;
            }
        }
        cout<<ans;
        fclose(stdin);fclose(stdout);
        return 0;
    }
  • 相关阅读:
    java:编写jar包加密工具,防止反编译
    Linux:CentOS-7常用命令
    MyBatis:MyBatis-Plus条件构造器EntityWrapper
    SpringBoot:SpringBoot项目的配置文件放在Jar包外加载
    机械学习导
    如何選擇最佳的 Wi-Fi 無線網路頻道,獲得最佳的傳輸速度(转载)
    解决ubuntu下filezilla登录ftp看不到中文目录和文件的问题 (转载)
    输入前几个字母,用箭头就能找出开头字母相同的历史命史
    Linux系统下使用split命令分割大文件 (转载)
    删除文件时排除特定文件 (转载)
  • 原文地址:https://www.cnblogs.com/shenben/p/6390598.html
Copyright © 2011-2022 走看看