• P1005 矩阵取数游戏


    传送门

    思路:

      △ 区间动规

      对于每行,有 f [ i ][ j ] 代表取区间 ] 的最大值。

      然后转移方程我们考虑,对于每一个新的 ]],有两种情况(下面定义 ]代表该行的每个数):

      ①先取前面的(]),再取剩下的 i+]]即i+]的最大值:2[i+1]j 2]即把接下来取的所有数乘上2,也就是把接下来取的所有数从2i变为x×2i+1即每次取都把之前的翻一倍,然后当前取的值 a [ i ]要乘上212

      ②先取后面的(]),再取剩下的 ]j]即j]的最大值:2f [ i ][ j-1 ] + 2a [ j ]同理

      故转移方程为 f [ i ][ j ] = max( 2f [ i+1 ][ j ]+2a [ i ],2f [ i ][ j-1 ] + 2a [ j ] )

    AC代码:

    #include<bits/stdc++.h>
    #define max(x,y) (x>y?x:y)
    using namespace std;
    __int128 f[105][105],ans;//_int128 (高精,比int多一位)(int:127)
    int n,m,len,Ans[105],mp[105][105],a[105];
    inline int read()
    {
        int kr=1,xs=0;
        char ls;
        ls=getchar();
        while(!isdigit(ls))
        {
            if(ls=='-')
            kr=-1;
            ls=getchar();
        }
        while(isdigit(ls))
        {
            xs=(xs<<1)+(xs<<3)+(ls^48);
            ls=getchar();
        }
        return xs*kr;
    }
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                mp[i][j]=read();
        for(int j=1;j<=n;++j)
        {
            memset(f,0,sizeof(f));
            for(int i=1;i<=m;++i)a[i]=mp[j][i];
            for(int len=0;len<=m;++len)
            {
                for(int i=1;i<=m-len;++i)
                {
                    f[i][i+len]=max((a[i]<<1)+(f[i+1][i+len]<<1),(f[i][i+len-1]<<1)+(a[i+len]<<1));
                }
            }
            ans+=f[1][m];
        }
        while(ans)
        {
            Ans[++len]=ans%10;
            ans/=10;
        }
        if(len==0)return printf("0"),0;
        for(int i=len;i>=1;--i)
            printf("%d",Ans[i]);
    return 0;
    }
  • 相关阅读:
    Android Studio使用
    VS.NET发送会议邮件程序原码
    C#中渐变色的代码实例,用于自绘菜单
    VS.NET获取某年某月的天数
    AJAX原理简要说明及实例
    ASP.NET下增加定时器功能
    VS.NET发送普通邮件原码
    保存xml到server实例
    VS.NET通过OUTLOOK发邮件
    利用IE打印的一点实例代码
  • 原文地址:https://www.cnblogs.com/lck-lck/p/9688369.html
Copyright © 2020-2023  润新知