P1005 矩陣取數遊戲 DP+__int128

P1005 矩陣取數遊戲

鏈接在此https://www.luogu.org/problem/P1005

先考慮部分分60分
可以看到dp是可以穩穩地得到60分的。
而dp思路就是將每一行單獨求dp
dp方程式爲

			dp[i][j]=max(dp[i-1][j]+a[i]*fpow(2,n-(j-i)+1),dp[i][j]);
			dp[i][j]=max(dp[i][j+1]+a[j]*fpow(2,n-(j-i)+1),dp[i][j]);

其中fpow爲快速冪(這裏有坑點)。表示2的(n-i+j+1)次方
然後i表示從開頭取取到了第i個
j表示從結尾取取到了第j個

i和j都是數組的序號而不是從左往右或從右往左的個數。

剩下的就是高精度。手懶用了int128

要注意的是print時注意特判0的情況
還有fpow中的變量類型也要是int128

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a); i<=(b);++i)
#define MAXN 100010
#define ll long long
#define bll __int128
using namespace std;
void read(int &x){
	x=0; char c=getchar(); int f=1;
	for(;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for(;isdigit(c);c=getchar()) x=x*10+c-'0'; x*=f;
}
bll fpow(bll a,bll b){
	bll ans=1;
	while (b>0){
		if (b%2)  ans*=a;
		a=a*a;	b=b/2;
	}
	return ans;
}
void print(bll x){
    if(!x) return;
    if(x) print(x/10);
    putchar(x%10+'0');
}
int n,m,a[MAXN];
bll dp[100][100];
int main(){
	bll ANS=0; 
	read(m); read(n);
	REP(QQ,1,m){
		memset(dp,0,sizeof(dp)); 
		memset(a,0,sizeof(a)); 
	for(int i(1);i<=n;++i) read(a[i]);
	for(int i(n+1);i>=1;i--) dp[0][i]=dp[0][i+1]+a[i]*fpow(2,n-i+1);
	REP(i,1,n)
		for(int j=n+1; j>i;j--){
			dp[i][j]=max(dp[i-1][j]+a[i]*fpow(2,n-(j-i)+1),dp[i][j]);
			dp[i][j]=max(dp[i][j+1]+a[j]*fpow(2,n-(j-i)+1),dp[i][j]);
		}
	bll ans=0; 
		REP(i,0,n){
			ans=max(ans,dp[i][i+1]);
		}
		ANS+=ans; 
	}
	if(ANS) 
	print(ANS); else cout<<"0"<<endl; 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章