zoukankan      html  css  js  c++  java
  • Codevs_1166_[NOIP2007]_矩阵取数游戏_(动态规划+高精度)

    描述


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

    分析


      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 const int maxn=50;
      8 
      9 struct Bign{
     10     int x[maxn],cnt;
     11     int & operator [] (int id){ return x[id]; }
     12     Bign(){ memset(x,0,sizeof x); }//空的构造函数
     13     Bign(int num){ *this=num; }//赋一个数字的构造函数
     14     Bign(char* num){ *this=num; }//赋一个字符串数字的构造函数
     15     Bign operator = (const char* num){//字符串的赋值函数
     16         memset(x,0,sizeof x); cnt=strlen(num);
     17         for(int i=1;i<=cnt;i++) x[i]=num[cnt-i-1]-'0';
     18         return *this;
     19     }
     20     Bign operator = (int num){//数字的赋值函数
     21         memset(x,0,sizeof x); cnt=0;
     22         while(num){
     23             x[++cnt]=num%10;
     24             num/=10;
     25         }
     26         return *this;
     27     }
     28     Bign operator + (Bign y) const{//加法
     29         Bign z; z.cnt=max(cnt,y.cnt);
     30         for(int i=1;i<=z.cnt;i++){
     31             z[i]+=x[i]+y[i];
     32             if(z[i]>=10) z[i+1]++, z[i]-=10;
     33         }
     34         if(z[z.cnt+1]) z.cnt++;//加法至多多出一位
     35         return z;
     36     }
     37     Bign operator - (Bign y) const{//减法
     38         Bign z; z.cnt=cnt;
     39         for(int i=1;i<=z.cnt;i++){
     40             z[i]+=x[i]-y[i];
     41             if(z[i]<0) z[i+1]--, z[i]+=10;
     42         }
     43         while(z.cnt&&!z[z.cnt]) z.cnt--;//减法可能会少很多位
     44         return z;
     45     }
     46      Bign operator * (Bign y) const{//乘法
     47         Bign z;
     48         for(int i=1;i<=cnt;i++)
     49             for(int j=1;j<=y.cnt;j++)
     50                 z[i+j-1]+=x[i]*y[j],z[i+j]+=z[i+j-1]/10, z[i+j-1]%=10;
     51         z.cnt=cnt+y.cnt;//乘法后结果的位数为cnt1+cnt2或cnt1+cnt2-1.
     52         if(!z[z.cnt]) z.cnt--;
     53         return z;
     54     }
     55     Bign operator / (Bign y) const{//除法
     56         Bign z=*this,d=0;
     57         for(int i=cnt;i;i--){
     58             d=d*10+x[i];
     59             for(int j=0;j<10;j++)
     60                 if(d<y*(j+1)){
     61                     z[i]=j;
     62                     d=d-y*j;
     63                     break;
     64                 }
     65         }
     66         while(z.cnt&&!z[z.cnt]) z.cnt--;
     67         return z;
     68     }
     69     Bign operator % (Bign y) const{//取模
     70         Bign d=0;
     71         for(int i=cnt;i;i--){
     72             d=d*10+x[i];
     73             for(int j=0;j<10;j++)
     74                 if(d<y*(j+1)){
     75                     d=d-y*j;
     76                     break;
     77                 }
     78         }
     79         return d;
     80     }
     81     Bign &operator += (Bign y){ *this=*this+y; return *this; }
     82     Bign &operator -= (Bign y){ *this=*this-y; return *this; }
     83     Bign &operator *= (Bign y){ *this=*this*y; return *this; }
     84     Bign &operator /= (Bign y){ *this=*this/y; return *this; }
     85     Bign &operator %= (Bign y){ *this=*this%y; return *this; }
     86 
     87     bool operator < (Bign y){
     88         if(cnt!=y.cnt) return cnt<y.cnt;
     89         for(int i=cnt;i;i--)
     90             if(x[i]!=y[i]) return x[i]<y[i];
     91         return false;
     92     }
     93     bool operator > (Bign y){ return y<*this; }
     94     bool operator <= (Bign y){ return!(y<*this); }
     95     bool operator >= (Bign y){ return!(*this<y); }
     96     bool operator != (Bign y){ return y<*this||*this<y; }
     97     bool operator == (Bign y){ return!(y<*this)&&!(*this<y); }
     98 }dp[100][100],a[100][100],ans;
     99 istream& operator >> (istream &in,Bign &x){//输入
    100     char s[maxn];
    101     scanf("%s",s+1); int len=strlen(s+1);
    102     for(int i=len;i;i--)
    103         x[len+1-i]=s[i]-'0';
    104     x.cnt=len;
    105     return in;
    106 }
    107 ostream& operator << (ostream &out,Bign &x){//输出
    108     for(int i=x.cnt;i;i--)
    109         out << x[i];
    110     if(!x.cnt) out << 0;
    111     return out;
    112 }
    113 
    114 int main(){
    115     int n,m;
    116     scanf("%d%d",&n,&m);
    117     Bign t=1;
    118     for(int i=1;i<=m;i++) t*=2;
    119     for(int i=1;i<=n;i++){
    120         memset(dp,0,sizeof dp);
    121         for(int j=1;j<=m;j++){
    122             cin >> a[i][j];
    123             dp[j][j]=t*a[i][j];
    124         }
    125         Bign tmp=t;
    126         for(int k=2;k<=m;k++){
    127             tmp/=2;
    128             for(int l=1;l<=m-k+1;l++){
    129                 int r=l+k-1;
    130                 if(dp[l+1][r]+a[i][l]*tmp>dp[l][r-1]+a[i][r]*tmp)
    131                     dp[l][r]=dp[l+1][r]+a[i][l]*tmp;
    132                 else
    133                     dp[l][r]=dp[l][r-1]+a[i][r]*tmp;
    134             }
    135         }
    136         ans+=dp[1][m];
    137     }
    138     cout << ans <<endl;
    139     return 0;
    140 }
    View Code
  • 相关阅读:
    linux 查看磁盘空间大小
    CSS里常见的块级元素和行内元素
    bootstrap改变上传文件按钮样式,并显示已上传文件名
    深度剖析:PHP中json_encode与json_decode
    2016 版 Laravel 系列入门教程
    支付宝私钥和公钥的生成方法
    iOS企业包安装注意事项详解(解决提示iPhone未受信任的问题)
    libevent的入门学习-库的安装【转】
    ibevent 和 libev 提高网络应用性能【转】
    libevent学习笔记 一、基础知识【转】
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5554758.html
Copyright © 2011-2022 走看看