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 }
  • 相关阅读:
    (转) CS0234: 命名空间“System.Web.Mvc”中不存在类型或命名空间名称“Ajax”(是否缺少程序集引用?)
    服务器修改密码后,发布的网站报“500内部服务器错误”
    关于“/”应用程序中的服务器错误 之解决方案
    (转)根据IP返回对应的位置信息
    (转)C# DateTime格式化大全
    线包字效果
    (转)VS2012网站发布详细步骤
    HTML5 为什么这么火?
    百度地图下拉框搜索建议,并自动添加标注点
    js中检查时间段列表是否有交叉
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/13837862.html
Copyright © 2011-2022 走看看