您的位置:首页 > 其它

洛谷P1005&NOIP2007 矩阵取数游戏

2016-10-28 20:45 330 查看
(抄的高精度模板233

由于要取完所有的数,所以原题可转化为在每一行上取数,累加所有行的答案即可

f[k][I][j]表示在第k行从1取到I,从j取到m的答案

f[k][I][j]=max(f[k][I-1][j]+2^(m-j+i-1)*a[k][I-1],f[k][i][j+1]+2^(m-j+i-1)*a[k][j+1])

(第一次写把a[k][I-1]习惯性地写成了a[I-1][j],调了好久。。。。

(刚开始本想加一维表示第几次取,然后发现当I和j固定时,次数就固定了。。。。

#include<iostream>
#include<cstring>
#include<cstdio>
#define LL long long
#define dp f
#define maxn 82
using namespace std;
struct BIGNUM {
short num[35],len;
BIGNUM(){memset(num,0,sizeof(num));len=1;}
BIGNUM operator = (const char str[]) {
len=strlen(str);
for(int i=0;i<len;i++)
num[i]=str[len-i-1]-'0';
while(num[len-1]==0&&len>1) len--;
return *this;
}
BIGNUM operator = (const int n) {
int tmp=n;
len=1;
do {
num[len-1]=tmp%10;
tmp/=10;len++;
}while(tmp>0);
while(num[len-1]==0&&len>1) len--;
return *this;
}
BIGNUM operator + (const BIGNUM &rhs) const {
BIGNUM tmp;
tmp.len=max(len,rhs.len)+1;
for(int i=0;i<tmp.len;i++) {
tmp.num[i]+=num[i]+rhs.num[i];
tmp.num[i+1]=tmp.num[i]/10;
tmp.num[i]%=10;
}
while(tmp.num[tmp.len-1]==0&&tmp.len>1) tmp.len--;
return tmp;
}
BIGNUM operator * (const BIGNUM &rhs) const {
BIGNUM tmp;
tmp.len=len+rhs.len;
for(int i=0;i<len;i++)
for(int j=0;j<rhs.len;j++) {
tmp.num[i+j]+=num[i]*rhs.num[j];
tmp.num[i+j+1]+=tmp.num[i+j]/10;
tmp.num[i+j]%=10;
}
while(tmp.num[tmp.len-1]==0&&tmp.len>1) tmp.len--;
return tmp;
}
bool operator < (const BIGNUM &rhs) const {
if(len>rhs.len) return false;
if(len<rhs.len) return true;
for(int i=len-1;i>=0;i--)
if(num[i]!=rhs.num[i]) return num[i]<rhs.num[i];
return false;
}
void print() {
for(int i=len-1;i>=0;i--) printf("%d",num[i]);
}
};
BIGNUM dp[82][82][82],ans,a[maxn][maxn];
int main(){
ios::sync_with_stdio(false);
int n,m;cin>>n>>m;
int a0[82][82];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>a0[i][j];
a[i][j]=a0[i][j];
}
BIGNUM pow[82];
pow[0]=1;pow[1]=2;
for(int i=2;i<=maxn-1;i++)
pow[i]=pow[i-1]*pow[1];
for(int k=1;k<=n;k++){
BIGNUM ansx;
for(int i=1;i<=m;i++){
for(int j=m;j>=i-1;j--){
int t=m-(j-i)-1;
BIGNUM lf=dp[k][i-1][j],ri=dp[k][i][j+1];
BIGNUM scl=pow[t]*a[k][i-1];
BIGNUM scr=pow[t]*a[k][j+1];
BIGNUM s=max(lf+scl,ri+scr);
dp[k][i][j]=s;
}
ansx=max(ansx,dp[k][i][i-1]);
}
ans=ansx+ans;
}
ans.print();
return 0;
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: