• 区间型动态规划 之 CODE[VS] 矩阵取数游戏 (2007年NOIP全国联赛提高组)


    /*
    分析:
    对于n行输入,各行之间是独立的,只需要找到各行的最大值,它们的和即为答案。
    由于:1<=n, m<=80,0<=aij<=1000,所以最大会出现 1000*(2^80) => 高精度计算
     
    dp[i][j] := 每行取第i到j个数可得到的最大值。
    对于输入的任一行a[m],第x次取数的状态转移为:
    dp[i][j] = 2*max(dp[i+1][j]+arr[i],dp[i][j-1]+arr[j])
    (正常取数是由外向内,但步长是由小到大,相当于取数是由内向外,所以2要乘在外面,这样倍数会自然乘上)
     
    */
      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <cstdio>
      4 #include <cstddef>
      5 #include <iterator>
      6 #include <algorithm>
      7 #include <locale>
      8 #include <cmath>
      9 #include <vector>
     10 #include <cstring>
     11 using namespace std;
     12 const int INF = 0x3f3f3f3f;
     13 const int MaxN = 85;
     14 const int MaxLen = 30;
     15 
     16 int n, m;
     17 
     18 struct node 
     19 {
     20     int arr[MaxLen];
     21     int len;
     22     node ()
     23     {
     24         memset(arr, 0, sizeof(arr));
     25         len = 0;
     26     }
     27 };
     28 
     29 int arr[MaxN];
     30 
     31 // a*2
     32 node Mul(node a)
     33 {
     34     int carry = 0;
     35     for (int i = 0; i < a.len; ++i)
     36     {
     37         a.arr[i] = (a.arr[i] << 1) + carry;
     38         carry = a.arr[i] / 10;
     39         a.arr[i] %= 10;
     40     }
     41     if (carry != 0)
     42     {
     43         a.arr[a.len] = carry;
     44         ++(a.len);
     45     }
     46     return a;
     47 }
     48 
     49 node Add(node a, int val)
     50 {
     51     int carry = 0;
     52     for (int i = 0; i < a.len; ++i) {
     53         a.arr[i] += (val % 10 + carry);
     54         val /= 10;
     55         carry = a.arr[i] / 10;
     56         a.arr[i] %= 10;
     57     }
     58     while (val)
     59     {
     60         a.arr[a.len] += (val % 10 + carry);
     61         val /= 10;
     62         carry = a.arr[a.len] / 10;
     63         a.arr[a.len] %= 10;
     64         ++(a.len);
     65     }
     66     if (carry)
     67     {
     68         a.arr[a.len] = carry;
     69         ++(a.len);
     70     }
     71     return a;
     72 }
     73 
     74 
     75 node Add(node a, node b)
     76 {
     77     node tmp;
     78     int carry = 0;
     79     int len = max(a.len, b.len);
     80     for (int i = 0; i < len; ++i)
     81     {
     82         tmp.arr[i] = a.arr[i] + b.arr[i] + carry;
     83         carry = tmp.arr[i] / 10;
     84         tmp.arr[i] = tmp.arr[i] % 10;
     85         ++(tmp.len);
     86     }
     87     if (carry != 0)
     88     {
     89         tmp.arr[tmp.len] = carry;
     90         ++(tmp.len);
     91     }
     92 
     93     return tmp;
     94 }
     95 
     96 node Cmp(node a, node b)
     97 {
     98     if (a.len < b.len)
     99     {
    100         return b;
    101     }
    102     if (a.len > b.len)
    103     {
    104         return a;
    105     }
    106 
    107     for (int i = a.len - 1; i >= 0; --i)
    108     {
    109         if (a.arr[i] == b.arr[i]) continue;
    110         if (a.arr[i] > b.arr[i])
    111         {
    112             return a;
    113         }
    114         else {
    115             return b;
    116         }
    117     }
    118     return a;
    119 }
    120 
    121 
    122 int main() 
    123 {
    124     node ans;
    125     cin >> n >> m;
    126     for (int tn = 0; tn < n; ++tn) 
    127     {
    128         node dp[MaxN][MaxN];
    129         for (int tm = 0; tm < m; ++tm)
    130         {
    131             cin >> arr[tm];
    132             // 初始化:dp[i][i] = (arr[i]<<1)
    133             int tmp = (arr[tm] << 1);
    134             // 不用while循环,防止 tmp=0
    135             do
    136             {
    137                 dp[tm][tm].arr[dp[tm][tm].len] = tmp % 10;
    138                 ++(dp[tm][tm].len);
    139                 tmp /= 10;
    140             } while (tmp);
    141         }
    142         for (int k = 1; k < m; ++k) 
    143         {
    144             for (int i = 0; (i + k) < m; ++i)
    145             {
    146                 /*node tmp1 = Add(dp[i + 1][i + k], arr[i]);
    147                 node tmp2 = Mul(Add(dp[i + 1][i + k], arr[i]));*/
    148                 dp[i][i + k] = Mul(Cmp(Add(dp[i + 1][i + k], arr[i]), Add(dp[i][i + k - 1], arr[i+k])));
    149             }
    150         }
    151         ans = Add(ans, dp[0][m - 1]);
    152     }
    153     for (int i = ans.len - 1; i >= 0; --i) 
    154     {
    155         cout << ans.arr[i];
    156     }
    157     cout << endl;
    158 
    159     
    160 #ifdef HOME
    161     cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl;
    162 #endif
    163     return 0;
    164 }
    
    
     
  • 相关阅读:
    ==与===的区别判断
    javascript中new操作符
    javascript中toString和valueOf方法的区别
    数据库索引
    QVegas-一个升级版的TCP Vegas拥塞算法
    海量数据解决方式,知多少?
    最通俗易懂的网络应用层协议具体解释
    Android视图注入库:butterknife
    POJ 3210 : Coins
    ES6的新特性-让前后端差异越来越小
  • 原文地址:https://www.cnblogs.com/shijianming/p/4933280.html
Copyright © 2020-2023  润新知