• 10.10 上午 考试


    T1

    40:

    深搜

    60:

    m<=$10^5$时,可以dp,f[i]表示前i个星球最多的矿

    f[i]=max(f[i-4],f[i-7])+val[i]

    100:

    打表发现只有 1 2 3 5 6 9 10 13 17 不能由4、7组合出来

    所以只要把>18的距离离散成18,还像60那样dp就行了

    $O(18n)$

     

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    using namespace std;
    inline int read()
    {
        char q=getchar();int ans=0;
        while(q<'0'||q>'9')q=getchar();
        while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}
        return ans;
    }
    const int N=100006;
    struct JI
    {
        int pos,val;
        bool friend operator < (JI a,JI b)
        {
            return a.pos<b.pos;
        }
    }ji[N];
    
    int n,m;
    int f[N*20],hh[N*20];
    int ans;
    int len;
    
    void chu()
    {
        sort(ji+1,ji+1+n);
        int las=0,temp;
        for(int i=1;i<=n;++i)
        {
            if(ji[i].pos-ji[i-1].pos>17)
                temp=18;
            else
                temp=ji[i].pos-ji[i-1].pos;
            hh[las+temp]+=ji[i].val;
            las+=temp;
        }
        len=las;
    }
    
    void work()
    {
        int temp;
        mem(f,-60);
        f[0]=0;
        for(int i=0;i<=len;++i)
        {
            if(f[i]<-1000)
                continue;
            if(f[i+4]<f[i]+hh[i+4])
                f[i+4]=f[i]+hh[i+4];
            if(f[i+7]<f[i]+hh[i+7])
                f[i+7]=f[i]+hh[i+7];
        }
        for(int i=0;i<=len;++i)
            if(ans<f[i])
                ans=f[i];
    }
    
    int main(){
    
        n=read();m=read();
        for(int i=1;i<=n;++i)
            ji[i].val=read(),ji[i].pos=read();
        chu();
        work();
        cout<<ans;
    }
    T1

     

     

     

    T2

    Aavg 平均数

    原式可以化简:

    $$ (n+m-1)sum_{i=1}^{n+m-1}(A_i-Aavg)^2$$

    $$ ((n+m-1)sum_{i=1}^{n+m-1}A_{i}^{2})-sum^2$$

    定义f[i][j][k] 为i行j列当前sum=k时$A_{i}^2$的最小值
    然后从f[i-1][j][k]和f[i][j-1][k]转移就行了

     

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define dd double
    using namespace std;
    const int N=36;
    
    int T;
    int n,m,sum;
    int a[N][N];
    int f[33][33][27066];
    
    int work()
    {
        mem(f,60);
        int qqq=f[0][0][0];
        int hhh=n+m-1,temp;
        f[1][0][0]=0;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                for(int k=a[i][j];k<=sum;++k)
                {
                    if(f[i-1][j][k-a[i][j]]!=qqq)
                    {
                        temp=f[i-1][j][k-a[i][j]]+hhh*a[i][j]*a[i][j];
                        if(f[i][j][k]>temp)
                            f[i][j][k]=temp;
                    }
                    if(f[i][j-1][k-a[i][j]]!=qqq)
                    {
                        temp=f[i][j-1][k-a[i][j]]+hhh*a[i][j]*a[i][j];
                        if(f[i][j][k]>temp)
                            f[i][j][k]=temp;
                    }
                }
        int ans=0x7fffffff;
        for(int i=a[n][m];i<=sum;++i)
            if(f[n][m][i]!=qqq)
            {
                temp=f[n][m][i]-i*i;
                if(ans>temp)
                    ans=temp;
            }
        return ans;
    }
    
    int main(){
    
        //freopen("T2.in","r",stdin);
        //freopen("T2.out","w",stdout);
    
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            sum=0;
            for(int i=1;i<=n;++i)
                for(int j=1;j<=m;++j)
                {
                    scanf("%d",&a[i][j]);
                    sum+=a[i][j];
                }
            printf("%d
    ",work());
        }
    
    }
    T2

     

     

     

    T3

    M是非常小的,所以异或之后受影响的只是低位,再dfs的时候记录下来低位是那个的个数即可

    (我还在想异或会不会有什么结合律之类的...)

     

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    using namespace std;
    inline int read()
    {
        char q=getchar();int ans=0;
        while(q<'0'||q>'9')q=getchar();
        while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}
        return ans;
    }
    const int N=100006;
    struct son
    {
        int v,next,w;
    }a1[N*2];
    int first[N*2],e;
    void addbian(int u,int v,int w)
    {
        a1[e].v=v;
        a1[e].w=w;
        a1[e].next=first[u];
        first[u]=e++;
    }
    
    int n,M,mod;
    
    int gget()
    {
        int tt=M;
        while(tt!=(tt&(-tt)))
            tt-=(tt&(-tt));
        return tt<<1;
    }
    
    int fa[N],sh[N][21],xi[N][21];
    int xihe[N],shhe[N],size[N];
    int t[21];
    void dfs1(int x)
    {
        int temp;
        size[x]=1;
        for(int i=first[x];i!=-1;i=a1[i].next)
        {
            temp=a1[i].v;
            if(temp==fa[x])
                continue;
            fa[temp]=x;
            dfs1(temp);
            size[x]+=size[temp];
            xihe[x]+=(xihe[temp]+a1[i].w*size[temp]);
    
            mem(t,0);
            ++t[a1[i].w%mod];
            for(int j=0;j<mod;++j)
                t[(j+a1[i].w)%mod]+=xi[temp][j];
            for(int j=0;j<mod;++j)
                xi[x][j]+=t[j];
        }
    }
    
    int bb[21];
    void dfs2(int x)
    {
        int temp;
        for(int i=first[x];i!=-1;i=a1[i].next)
        {
            temp=a1[i].v;
            if(temp==fa[x])
                continue;
            shhe[temp]+=(shhe[x]+xihe[x]-(xihe[temp]+a1[i].w*size[temp])+(size[1]-size[temp])*a1[i].w);
    
            mem(t,0);mem(bb,0);
            ++t[a1[i].w%mod];
            for(int j=0;j<mod;++j)
                t[(j+a1[i].w)%mod]+=xi[temp][j];
            for(int j=0;j<mod;++j)
                t[j]=(xi[x][j]-t[j]+sh[x][j]);
            ++bb[a1[i].w%mod];
            for(int j=0;j<mod;++j)
                bb[(a1[i].w+j)%mod]+=t[j];
            for(int j=0;j<mod;++j)
                sh[temp][j]=bb[j];
    
            dfs2(temp);
        }
    }
    
    int main(){
    
        //freopen("T3.in","r",stdin);
    
        mem(first,-1);
    
        n=read();M=read();
        
        mod=gget();
        if(mod==0)mod=1;
        int tin1,tin2,tin3;
        for(int i=1;i<n;++i)
        {
            tin1=read();tin2=read();tin3=read();
            addbian(tin1,tin2,tin3);
            addbian(tin2,tin1,tin3);
        }
        dfs1(1);
        dfs2(1);
        int temp;
        for(int i=1;i<=n;++i)
        {
            temp=shhe[i]+xihe[i];
            for(int j=0;j<mod;++j)
                temp+=(sh[i][j]+xi[i][j])*((j^M)-j);
            printf("%d
    ",temp);
        }
    }
    T3

     

     

     

    总结:

    考试的时候,一定要努力想,不要脑子抽风...

  • 相关阅读:
    C#获取动态代码的值
    C#winform圆角窗体绘制
    linux下安装jdk&&Tomcat环境
    一些linux基础命令
    linux下安装python3
    迭代器和生成器
    内置函数
    PythonTwo
    yum对于包和软件的安装、升级和卸载总结
    Python基础
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7645398.html
Copyright © 2020-2023  润新知