您的位置:首页 > 其它

Codevs_1166_[NOIP2007]_矩阵取数游戏_(动态规划+高精度)

2016-06-02 23:13 393 查看

描述

http://codevs.cn/problem/1166/

 

分析

 

 

 

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn=50;

struct Bign{
int x[maxn],cnt;
int & operator [] (int id){ return x[id]; }
Bign(){ memset(x,0,sizeof x); }//空的构造函数
Bign(int num){ *this=num; }//赋一个数字的构造函数
Bign(char* num){ *this=num; }//赋一个字符串数字的构造函数
Bign operator = (const char* num){//字符串的赋值函数
memset(x,0,sizeof x); cnt=strlen(num);
for(int i=1;i<=cnt;i++) x[i]=num[cnt-i-1]-'0';
return *this;
}
Bign operator = (int num){//数字的赋值函数
memset(x,0,sizeof x); cnt=0;
while(num){
x[++cnt]=num%10;
num/=10;
}
return *this;
}
Bign operator + (Bign y) const{//加法
Bign z; z.cnt=max(cnt,y.cnt);
for(int i=1;i<=z.cnt;i++){
z[i]+=x[i]+y[i];
if(z[i]>=10) z[i+1]++, z[i]-=10;
}
if(z[z.cnt+1]) z.cnt++;//加法至多多出一位
return z;
}
Bign operator - (Bign y) const{//减法
Bign z; z.cnt=cnt;
for(int i=1;i<=z.cnt;i++){
z[i]+=x[i]-y[i];
if(z[i]<0) z[i+1]--, z[i]+=10;
}
while(z.cnt&&!z[z.cnt]) z.cnt--;//减法可能会少很多位
return z;
}
Bign operator * (Bign y) const{//乘法
Bign z;
for(int i=1;i<=cnt;i++)
for(int j=1;j<=y.cnt;j++)
z[i+j-1]+=x[i]*y[j],z[i+j]+=z[i+j-1]/10, z[i+j-1]%=10;
z.cnt=cnt+y.cnt;//乘法后结果的位数为cnt1+cnt2或cnt1+cnt2-1.
if(!z[z.cnt]) z.cnt--;
return z;
}
Bign operator / (Bign y) const{//除法
Bign z=*this,d=0;
for(int i=cnt;i;i--){
d=d*10+x[i];
for(int j=0;j<10;j++)
if(d<y*(j+1)){
z[i]=j;
d=d-y*j;
break;
}
}
while(z.cnt&&!z[z.cnt]) z.cnt--;
return z;
}
Bign operator % (Bign y) const{//取模
Bign d=0;
for(int i=cnt;i;i--){
d=d*10+x[i];
for(int j=0;j<10;j++)
if(d<y*(j+1)){
d=d-y*j;
break;
}
}
return d;
}
Bign &operator += (Bign y){ *this=*this+y; return *this; }
Bign &operator -= (Bign y){ *this=*this-y; return *this; }
Bign &operator *= (Bign y){ *this=*this*y; return *this; }
Bign &operator /= (Bign y){ *this=*this/y; return *this; }
Bign &operator %= (Bign y){ *this=*this%y; return *this; }

bool operator < (Bign y){
if(cnt!=y.cnt) return cnt<y.cnt;
for(int i=cnt;i;i--)
if(x[i]!=y[i]) return x[i]<y[i];
return false;
}
bool operator > (Bign y){ return y<*this; }
bool operator <= (Bign y){ return!(y<*this); }
bool operator >= (Bign y){ return!(*this<y); }
bool operator != (Bign y){ return y<*this||*this<y; }
bool operator == (Bign y){ return!(y<*this)&&!(*this<y); }
}dp[100][100],a[100][100],ans;
istream& operator >> (istream &in,Bign &x){//输入
char s[maxn];
scanf("%s",s+1); int len=strlen(s+1);
for(int i=len;i;i--)
x[len+1-i]=s[i]-'0';
x.cnt=len;
return in;
}
ostream& operator << (ostream &out,Bign &x){//输出
for(int i=x.cnt;i;i--)
out << x[i];
if(!x.cnt) out << 0;
return out;
}

int main(){
int n,m;
scanf("%d%d",&n,&m);
Bign t=1;
for(int i=1;i<=m;i++) t*=2;
for(int i=1;i<=n;i++){
memset(dp,0,sizeof dp);
for(int j=1;j<=m;j++){
cin >> a[i][j];
dp[j][j]=t*a[i][j];
}
Bign tmp=t;
for(int k=2;k<=m;k++){
tmp/=2;
for(int l=1;l<=m-k+1;l++){
int r=l+k-1;
if(dp[l+1][r]+a[i][l]*tmp>dp[l][r-1]+a[i][r]*tmp)
dp[l][r]=dp[l+1][r]+a[i][l]*tmp;
else
dp[l][r]=dp[l][r-1]+a[i][r]*tmp;
}
}
ans+=dp[1][m];
}
cout << ans <<endl;
return 0;
}
View Code

 

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