zoukankan      html  css  js  c++  java
  • 洛谷 P1005 矩阵取数游戏 & [NOIP2007提高组](区间dp,高精度)

    传送门


    解题思路

    每行互不影响,所以分开处理,对于每一行,很显然是个区间dp,我们用dp[i][j]表示区间[i..j]的得分和的最大值,注意每次加一个数的顺序是先加上数再集体乘2。

    恶心的地方在于需要写高精(学校比赛懒得写,所以只拿了60分),需要一个高精度+int,一个高精度*2,一个高精度+高精度三个函数,同时因为dp要取max,所以需要重定义struct里的<。

    AC代码

     1 //dp[i][j]表示区间[i..j]的最大值 dp[i][j]=max(dp[i+1][j]+a[i]*k,dp[i][j-1]+a[j]*k) 
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<cstdio>
     6 using namespace std;
     7 long long n,m,a[85];
     8 struct node{
     9     int shu[55];
    10     bool operator <(const node b) const {
    11         if(shu[0]!=b.shu[0]) return shu[0]<b.shu[0];
    12         for(int i=shu[0];i>=1;i--){
    13             if(shu[i]!=b.shu[i]) return shu[i]<b.shu[i];
    14         }
    15         return 1;
    16     }
    17 }dp[85][85],anss;
    18 node add(node a,int x){
    19     a.shu[1]+=x;
    20     int cnt=1;
    21     while(cnt<a.shu[0]||a.shu[cnt]>=10){
    22         a.shu[cnt+1]+=a.shu[cnt]/10;
    23         a.shu[cnt]%=10;
    24         cnt++;
    25     }
    26     a.shu[0]=max(a.shu[0],cnt);
    27     return a;
    28 }
    29 node cheng(node a,int x){
    30     int cnt=a.shu[0];
    31     for(int i=1;i<=cnt;i++){
    32         a.shu[i]*=x;
    33     }
    34     cnt=1;
    35     while(cnt<a.shu[0]||a.shu[cnt]>=10){
    36         a.shu[cnt+1]+=a.shu[cnt]/10;
    37         a.shu[cnt]%=10;
    38         cnt++;
    39     }
    40     a.shu[0]=max(a.shu[0],cnt);
    41     return a;
    42 }
    43 node add2(node a,node b){
    44     int cntt=max(a.shu[0],b.shu[0]);
    45     for(int i=1;i<=cntt;i++) a.shu[i]+=b.shu[i];
    46     int cnt=1;
    47     while(cnt<cntt||a.shu[cnt]>=10){
    48         a.shu[cnt+1]+=a.shu[cnt]/10;
    49         a.shu[cnt]%=10;
    50         cnt++;
    51     }
    52     a.shu[0]=max(a.shu[0],cnt);
    53     return a;
    54 }
    55 int main(){
    56     cin>>n>>m;
    57     for(int hang=1;hang<=n;hang++){
    58         memset(dp,0,sizeof(dp));
    59         for(int i=1;i<=m;i++) cin>>a[i];
    60         for(int i=1;i<=m;i++) dp[i][i]=add(dp[i][i],2*a[i]);
    61         for(int k=1;k<m;k++){
    62             for(int i=1;i<=m-k;i++){
    63                 int j=i+k; 
    64                 dp[i][j]=cheng(max(add(dp[i+1][j],a[i]),add(dp[i][j-1],a[j])),2);
    65             }
    66         }
    67         anss=add2(anss,dp[1][m]);
    68     }
    69     for(int i=anss.shu[0];i>=1;i--){
    70         cout<<anss.shu[i];
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    JedisConnectionException: java.net.ConnectException: Connection refused
    启动tomcat时 错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099的解决办法
    JAVA 判断一个字符串是不是一个合法的日期格式
    升级openssl
    Linux操作路由
    Linux的用户行为审计
    升级gdb
    Linux的运行级别
    sudo的用法
    Linux缓存清理
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/13837862.html
Copyright © 2011-2022 走看看