题干解析
很明显的 区间dp,刷过板子题的dalao们肯定可以看出来。 所以dp部分就是板子题。
思路详解
这题dp就是按题目说的去做就好。(还能再明显吗) 3 2 1 开大!!!
d
i
s
[
i
]
[
j
]
=
m
a
x
(
d
i
s
[
i
]
[
k
]
+
d
i
s
[
k
+
1
]
[
j
]
+
(
a
[
j
]
+
a
[
i
]
)
∗
a
[
k
]
)
;
dis[i][j]=max(dis[i][k]+dis[k+1][j]+(a[j]+a[i])*a[k]);
d i s [ i ] [ j ] = m a x ( d i s [ i ] [ k ] + d i s [ k + 1 ] [ j ] + ( a [ j ] + a [ i ] ) ∗ a [ k ] ) ; ps.因为 这样帅气 现在讨论的是纯dp,所以用了max 最后要跑递归来找过程 (详见代码)
代码
#include <bits/stdc++.h>
using namespace std;
int n, a[ 1001 ] , b[ 1001 ] , f[ 1001 ] [ 1001 ] , dis[ 1001 ] [ 1001 ] , ans[ 1001 ] [ 1001 ] , sum, print[ 1001 ] [ 1001 ] , u[ 1001 ] ;
inline void jqsh ( int x, int y, int t) {
int k= ans[ x] [ y] ;
if ( ! k) return ;
sum= max ( sum, t) ;
print[ t] [ ++ print[ t] [ 0 ] ] = k;
if ( x== y) return ;
jqsh ( x, k, t+ 1 ) ;
jqsh ( k+ 1 , y, t+ 1 ) ;
return ;
}
int main ( ) {
scanf ( "%d" , & n) ;
for ( int i= 1 ; i<= n; i++ )
scanf ( "%d" , & a[ i] ) ;
for ( int i= n- 1 ; i>= 1 ; i-- ) {
for ( int j= i+ 1 ; j<= n; j++ ) {
for ( int k= i; k< j; k++ ) {
if ( dis[ i] [ j] < dis[ i] [ k] + dis[ k+ 1 ] [ j] + ( a[ j] + a[ i] ) * a[ k] ) {
dis[ i] [ j] = dis[ i] [ k] + dis[ k+ 1 ] [ j] + ( a[ j] + a[ i] ) * a[ k] ;
ans[ i] [ j] = k;
f[ k] [ 1 ] = i; f[ k] [ 2 ] = j;
}
}
}
}
printf ( "%d\n" , dis[ 1 ] [ n] ) ;
jqsh ( 1 , n, 1 ) ;
for ( int i= 1 ; i<= sum; i++ )
for ( int j= 1 ; j<= print[ i] [ 0 ] ; j++ )
printf ( "%d " , print[ i] [ j] ) ;
printf ( "\n" ) ;
return 0 ;
}