首页 > 分享 > 洛谷 P1005 矩阵取数游戏

洛谷 P1005 矩阵取数游戏

传送门:洛谷 P1005 矩阵取数游戏
算法分析:

每次取数时须从每行各取走一个元素,共 (n) 个。经过 (m) 次后取完矩阵内所有元素;
每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分(=)被取走的元素值(times 2^i),其中 (i) 表示第 (i) 次取数(从(1)开始编号);
游戏结束总得分为 (m) 次取数得分之和。

故只要每一次考虑一行上的状况即可。
设现在在第 (t) 行, (dp[i][j]) 表示最后取 (i) , (j) 能得到的最大分数值,则这一行的答案就为 (dp[1][m])
(dp[i][j]=max{dp[i+1][j]+a[t][i]times2^{m+i-j},dp[i][j+1]+a[t][j]times2^{m+i-j}})
其中 (dp[i][i]=a[i]times 2^m)
附注:本题需用高精度,在本题里使用了重载运算符

时间复杂度:(O(n^3))

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxN=100,maxM=80; struct bign { int len,s[maxN+1]; bign() { memset(s,0,sizeof(s)); len=1; } bign(int num) {*this=num;} bign(const char *num) {*this=num;} bign operator=(const int num) { char s[maxN+1]; sprintf(s,"%d",num); *this=s; return *this; } bign operator=(const char *num) { for(int i=0;num[i]=='0';num++); len=strlen(num); for(int i=0;i<len;i++) s[i]=num[len-i-1]-'0'; return *this; } bign operator+(const bign &b) const { bign c; c.len=0; for(int i=0,g=0;g||i<max(len,b.len);i++) { int x=g; if(i<len) x+=s[i]; if(i<b.len) x+=b.s[i]; c.s[c.len++]=x%10; g=x/10; } return c; } bign operator+=(const bign &b) { *this=*this+b; return *this; } void clear() {while(len>1 && !s[len-1]) len--;} bign operator*(const bign &b) { bign c; c.len=len+b.len; for(int i=0;i<len;i++) for(int j=0;j<b.len;j++) c.s[i+j]+=s[i]*b.s[j]; for(int i=0;i<c.len;i++) { c.s[i+1]+=c.s[i]/10; c.s[i]%=10; } c.clear(); return c; } bign operator*=(const bign &b) { *this=*this*b; return *this; } bool operator<(const bign &b) { if(len!=b.len) return len<b.len; for(int i=len-1;i>=0;i--) if(s[i]!=b.s[i]) return s[i]<b.s[i]; return false; } bool operator>(const bign &b) { if(len!=b.len) return len>b.len; for(int i=len-1;i>=0;i--) if(s[i]!=b.s[i]) return s[i]>b.s[i]; return false; } bool operator==(const bign &b) { return !(*this>b) && !(*this<b); } bool operator!=(const bign &b) { return !(*this==b); } bool operator<=(const bign &b) { return *this<b || *this==b; } bool operator>=(const bign &b) { return *this>b || *this==b; } string str() const { string res=""; for(int i=0;i<len;i++) res=char(s[i]+'0')+res; return res; } }; istream& operator>>(istream &in,bign &x) { string s; in>>s; x=s.c_str(); return in; } ostream& operator<<(ostream &out,const bign &x) { out<<x.str(); return out; } int n,m; bign a[maxM+1][maxM+1]; bign dp[maxM+1][maxM+1]; bign two[maxM+1]; bign ans; inline int read(); void work(int); int main() {n=read(); m=read();ans.clear();for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j];two[1]=2;for(int i=2;i<=m;i++)two[i]=(bign)2*two[i-1];for(int t=1;t<=n;t++) work(t);cout<<ans; return 0; } void work(int t) {for(int i=0;i<=maxM;i++)for(int j=0;j<=maxM;j++)for(int k=0;k<=maxM;k++)dp[i][j].clear();for(int i=1;i<=m;i++) dp[i][i]=a[t][i]*two[m];for(int len=1;len<m;len++)for(int i=1;i<=m-len;i++){bign x=a[t][i]*two[m-len]+dp[i+1][i+len];bign y=a[t][i+len]*two[m-len]+dp[i][i+len-1];if(x>y) dp[i][i+len]=x;else dp[i][i+len]=y;}ans+=dp[1][m]; } inline int read() { char ch=getchar(); int f=1,num=0; while((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if(ch=='-') {f=-1; ch=getchar();} while(ch>='0' && ch<='9') { num=num*10+ch-'0'; ch=getchar(); } return num*f; }

相关知识

洛谷 P1077 摆花 题解
矩阵乘法(摆花)
伊洛纳游戏代理 费用多少钱
苹果ios付费游戏免费下载iphone账号id花夏数娱
咏洛赋
花名怎么取
打造智慧文旅云产品矩阵 拈花云科引领文旅产业数智化转型
洛谷P1854 花店橱窗布置解题报告
投石科技公共空间装置动态艺术雕塑大型LED矩阵系列
上病下取疗痄腮

网址: 洛谷 P1005 矩阵取数游戏 https://m.huajiangbk.com/newsview990186.html

所属分类:花卉
上一篇: 带藤字的网名
下一篇: 洛谷 P4667 Switch