矩阵选数——高精度
难点:转移方程的确定;高精度;
首先本题可以逐行考虑,然后把每行的最大值相加,就是最终结果。而每一行的转移方程为:
f[i][j]=2*max{f[i+1][j]+a[i],f[i][j-1]+a[j]}
结合循环分析转移方程:
for(k=1;k<=m;k++)
for(i=1;i<=m-k+1;i++)
循环是逐个增加考虑元素的个数的。k代表元素个数,i代表起始元素,j=i+k-1,是末元素的
下标。“f[i+1][j]+a[i],f[i][j-1]+a[j]”代表取头或取尾元素,选其中最大的,然后乘以2.
之所以乘以2,代表i或者j元素是最先取的,故乘以2.而既然i或j是最先取的,那么前面状态的元
素当然要向后推一次取,所以乘以2.那么f[i][j]就代表从i到j的元素,第一个取取i或j
得到的最大值。
代码
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 int f[81][81][80],sum[80];
5 int a[81][81],s2[80];
6 int n,m,sf[81][81],sa[81];
7 char a1[81];
8 FILE *in,*out;
9
10 int plus(int *p,int *q,int l1,int l2,int *k)
11 {
12 int i,c,s=0,l;
13 if(l1>l2)l=l1;
14 else l=l2;
15 for(i=0;i<l;i++)
16 {
17 s+=p[i]+q[i];
18 c=s%10;
19 s=s/10;
20 k[i]=c;
21 }
22
23 while(s!=0)
24 {
25 c=s%10;
26 s=s/10;
27 k[i++]=c;
28 }
29 return i;
30 }
31
32 int max(int *p,int *q,int l1,int l2)
33 {
34 if(l1>l2)return 1;
35 else
36 if(l1<l2)return 0;
37 else
38 {
39 int i;
40 for(i=l2-1;i>=0;i--)
41 if(p[i]>q[i])return 1;
42 else
43 if(q[i]>p[i])return 0;
44 return 0;
45 }
46 }
47
48
49 int main(){
50 in=fopen("game7.in","r");
51 out=fopen("game.ans","w");
52 fscanf(in,"%d %d\n",&n,&m);
53 int i,j,j1,k,w,i1,ls=0,lss;
54 int le1,le2;
55 int x;
56 memset(sum,0,sizeof(sum));
57
58 for(i1=1;i1<=n;i1++)
59 {
60 memset(a1,0,sizeof(a1));
61 memset(f,0,sizeof(f));
62 memset(sf,0,sizeof(sf));
63 memset(a,0,sizeof(a));
64 for(j1=1;j1<=m;j1++)
65 {
66 fscanf(in,"%s",a1);
67 lss=strlen(a1);
68 sa[j1]=lss;
69 for(j=lss-1;j>=0;j--)
70 a[j1][lss-j-1]=a1[j]-'0';
71 }
72
73 for(k=1;k<=m;k++)
74 for(i=1;i<=m-k+1;i++)
75 {
76 memset(s2,0,sizeof(s2));
77 j=k+i-1;
78
79 sf[i][j]=plus(f[i+1][j],a[i],sf[i+1][j],sa[i],f[i][j]);
80 sf[i][j]=plus(f[i][j],f[i][j],sf[i][j],sf[i][j],f[i][j]);
81 le2=plus(f[i][j-1],a[j],sf[i][j-1],sa[j],s2);
82 le2=plus(s2,s2,le2,le2,s2);//加两次,相当于乘以2
83 if(max(s2,f[i][j],le2,sf[i][j]))
84 {
85 for(w=0;w<le2;w++)
86 f[i][j][w]=s2[w];
87 sf[i][j]=le2;
88 }
89 }
90 ls=plus(sum,f[1][m],ls,sf[1][m],sum);
91 }
92
93 for(i=ls-1;i>=0;i--)
94 fprintf(out,"%d",sum[i]);
95 fprintf(out,"\n");
96 fclose(in); fclose(out);
97 return 0;
98 }
99


浙公网安备 33010602011771号