矩阵取数游戏

矩阵取数游戏

https://ac.nowcoder.com/acm/problem/16645

不能直接1<<j,左移会溢出。所以需要数组记录或者直接快速幂;
想法比较直接,dp[j][k][2]取第j次时,到目前一共取了k次左边的,当前1为取左,0为取右;
正如紫书上说的,变量有几个,设几维;(比较粗暴的方法)

#include<bits/stdc++.h>
using namespace std;
__int128 mp[350][350],n,m,dp[350][350][2],ans;
inline __int128 read(){//快读
    __int128 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;
}
inline void print(__int128 x){//__int128输出
    if(x<0){
        putchar('-');
        x=-x;
    }
    if(x>9)
        print(x/10);
    putchar(x%10+'0');
}
__int128 power(__int128 a,__int128 b)//快速幂
{
    __int128 res=1;
    while(b)
    {
        if(b&1) res*=a;
        a*=a;
        b>>=1;
    }
    return res;
}
signed main()
{
    n=read(),m=read();
    for(__int128 i=1;i<=n;i++)
    {
        for(__int128 j=1;j<=m;j++)
        {
            mp[i][j]=read();
        }
    }
    for(__int128 i=1;i<=n;i++)//第i行
    {
        for(__int128 j=1;j<=m;j++)//次数
        {
            for(__int128 k=0;k<=j;k++)//取了k个左端点
            {
                __int128 h=power(2,j);
                if(k>0) dp[j][k][1]=max(dp[j][k][1],max(dp[j-1][k-1][0],dp[j-1][k-1][1])+h*mp[i][k]);
                dp[j][k][0]=max(dp[j][k][0],max(dp[j-1][k][0],dp[j-1][k][1])+h*mp[i][m-j+k+1]);
            }
        }
        __int128 ma1=0;
        for(__int128 k=0;k<=m;k++)
            ma1=max(ma1,max(dp[m][k][1],dp[m][k][0]));
        ans+=ma1;
        memset(dp,0,sizeof(dp));
    }
    print(ans);
}
全部评论

相关推荐

点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务