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
相关文章推荐
- 【转】iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势) -- 不错不错
- C primer plus 第十章 练习2:
- [直观学习排序算法] 视觉直观感受若干常用排序算法
- 软件开发技术逐步积累汇总
- 调用约定
- 基因数据处理47之ART基因序列数据生成器(仿真)
- The content of the adapter has changed but ListView did not receive a notification
- Android应用架构之Retrofit使用
- SHA-1加密算法原理
- 第二阶段冲刺9
- struts2拦截器
- #利用C语言-EasyX图形设计-制作简易计算器#
- XCODE中使用Main.Storyboard拉入控件并实现事件(Swift语言)
- 互联网中广泛使用的优秀框架
- 纯CSS苹果菜单
- Java之------IO从基础到加强(一)
- Android中网络通信的几种方式
- 关闭文件描述符-close
- centos screen 命令使用处理SSH连接中断问题
- Centos6.5 Nginx +Tomcat 集群搭建