1574: Matrix access game

1574: Matrix access game

Time limit: 1000 ms Memory limit: 524288 KB
Number of submissions: 618 Number of passes: 248
[Title description]

I often play a matrix access game with my classmates : For a given n×m matrix, each element aij in the matrix is ​​a non-negative integer. The rules of the game are as follows:

1. Each time you fetch a number, you must fetch one element from each row, a total of n, and fetch all elements m times.

2. Each element removed each time can only be the beginning or end of the line where the element is located.

3. Each fetch has a score, which is the sum of the fetch scores for each row. The fetch score for each row == the value of the removed element × 2i, where i represents the i-th fetch and counts from 1. .

4. At the end of the game , the total score is the sum of the scores of m times.

I want you to help write a program, for any matrix, you can find the maximum score after taking the number.

[Input]
Input includes n+1 lines. Positive integers separated by two spaces in the first line n,m m integers separated by spaces in each of the next n lines.

[Output] The
output is an integer, which is the maximum score after the input matrix is ​​taken.

[Input sample]
2 3
1 2 3
3 4 2
[Output sample]
82
[Prompt]
Sample explanation 1

First time: The first line takes the first element of the line, and the second line takes the end element. This time the score is 1×21+2×21=6;

Second time: Take the first element of both lines, this time the score is 2×22+3×22=20;

The third time: This time the score is 3×23+4×23=56, and the total score is 6+20+56=82.

Sample input 2

1 4
4 5 0 5
Sample output 2

122
sample input 3

2 10
96 56 54 46 86 12 23 88 80 43
16 95 18 29 30 53 88 83 64 67
Sample output 3

316994
data range and tips:

For 60% of the data, 1≤n, m≤30, the answer should not exceed 1016;

For 100% data, 1≤n, m≤80, 0≤ai, j≤1000.

Idea:
The interval dp with a bit of thinking content is different from other template intervals dp. For this question, we need to perform interval dp processing for each row, and we need to have high precision w(゚Д゚)w

Without high precision:

#include<bits/stdc++.h>
#define ull unsigned long long
#define maxn 105
using namespace std;

ull a[maxn][maxn],f[maxn][maxn];
ull p[maxn],ans=0,n,m;

void work(ull tmp)
{
    
    
	memset(f,0,sizeof(f));
	for(int i=1;i<=m;i++) f[i][i]=a[tmp][i]*p[m];//预处理出如果最后选择i的值
	for(int l=2;l<=m;l++)
	{
    
    
		for(int i=1;i+l-1<=m;i++){
    
    
			int j=i+l-1;
			f[i][j]=max(f[i+1][j]+a[tmp][i]*p[m-l+1],f[i][j-1]+a[tmp][j]*p[m-l+1]);
		}
	} 
	
	ans+=f[1][m];
	
 } 

int main()
{
    
    
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
    
    
			cin>>a[i][j];
		}
	p[1]=2;
	for(int i=2;i<=m;i++) p[i]=p[i-1]*2;
	for(int i=1;i<=n;i++) work(i);//对于每一行进行一次dp 
	
	cout<<ans<<'\n';	
	
}

High precision:

#include <bits/stdc++.h>
using namespace std;
const int N=85;
const int L=105,Power=4,Base=10000;
int n,m,a[N];
struct Bignum
{
    
    
    int a[L];
    Bignum(){
    
    memset(a,0,sizeof a);}
    Bignum(int x)
    {
    
    
        memset(a,0,sizeof a);
        while(x) {
    
    a[++*a]=x%10; x/=10;}
        return;
    }
    inline void Print()
    {
    
    
        int i;
        printf("%d",a[*a]);
        for(i=*a-1;i>=1;i--)
        {
    
    
            if(a[i]<1000) putchar('0');
            if(a[i]<100) putchar('0');
            if(a[i]<10) putchar('0');
            printf("%d",a[i]);
        }
        puts("");
        return;
    }
    inline void Init()
    {
    
    
        memset(a,0,sizeof a);
    }
}Bin[N],dp[N][N];
inline bool operator<(const Bignum &p,const Bignum &q)
{
    
    
    if(p.a[0]!=q.a[0]) return (p.a[0]<q.a[0])?1:0;
    int i;
    for(i=p.a[0];i>=1;i--) if(p.a[i]!=q.a[i])
    {
    
    
        return (p.a[i]<q.a[i])?1:0;
    }
    return 0;
}
inline Bignum max(Bignum p,Bignum q)
{
    
    
    return (p<q)?(q):(p);
}
inline Bignum operator+(const Bignum &p,const Bignum &q)
{
    
    
    int i;
    Bignum ans=p;
    for(i=1;i<=q.a[0];i++)
    {
    
    
        ans.a[i]+=q.a[i];
        if(ans.a[i]>=Base){
    
    ans.a[i+1]+=ans.a[i]/Base; ans.a[i]%=Base;}
    }
    while(ans.a[ans.a[0]+1]) ans.a[0]++;
    return ans;
}
inline Bignum operator*(const Bignum &p,const Bignum &q)
{
    
    
    int i,j;
    Bignum ans;
    ans.a[0]=p.a[0]+q.a[0];
    for(i=1;i<=p.a[0];i++)
    {
    
    
        for(j=1;j<=q.a[0];j++)
        {
    
    
            ans.a[i+j-1]+=p.a[i]*q.a[j];
            if(ans.a[i+j-1]>Base)
            {
    
    
                ans.a[i+j]+=ans.a[i+j-1]/Base;
                ans.a[i+j-1]%=Base;
            }
        }
    }
    while(!ans.a[ans.a[0]]) ans.a[0]--;
    return ans;
}
inline Bignum operator*(const Bignum &p,const int &q)
{
    
    
    int i;
    Bignum ans;
    ans.a[0]=p.a[0]+5;
    for(i=1;i<=p.a[0];i++)
    {
    
    
        ans.a[i]+=p.a[i]*q;
        if(ans.a[i]>Base)
        {
    
    
            ans.a[i+1]+=ans.a[i]/Base; ans.a[i]%=Base;
        }
    }
    while(!ans.a[ans.a[0]]) ans.a[0]--;
    return ans;
}
inline Bignum Solve()
{
    
    
    int i,j;
    for(i=1;i<=m;i++)
    {
    
    
        for(j=1;j+i-1<=m;j++)
        {
    
    
            int l=j,r=j+i-1;
            dp[l][r]=max(dp[l][r-1]+Bin[m-i+1]*a[r],dp[l+1][r]+Bin[m-i+1]*a[l]);
        }
    }
//    dp[1][m].Print();
    return dp[1][m];
}
int main()
{
    
    
    int i,j;
    Bignum ans;
    scanf("%d%d",&n,&m);
    Bin[0]=Bignum(1);
    for(i=1;i<=m;i++) Bin[i]=Bin[i-1]*2;
//    for(i=1;i<=m;i++)
//    {
    
    
//        Bin[i].Print();
//    }
//    puts("");
    for(i=1;i<=n;i++)
    {
    
    
        for(j=1;j<=m;j++) scanf("%d",&a[j]);
        ans=ans+Solve();
    }
    ans.Print();
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_52308504/article/details/114077701