洛谷 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 }

 

posted @ 2020-10-18 23:24  尹昱钦  阅读(130)  评论(0编辑  收藏  举报