P1063 能量项链
输入输出样例
输入 #1<button class="copy-btn lfe-form-sz-middle" data-v-370e72e2="" data-v-52f2d52f="" type="button">复制</button>
4 2 3 5 10
输出 #1<button class="copy-btn lfe-form-sz-middle" data-v-370e72e2="" data-v-52f2d52f="" type="button">复制</button>
710
说明/提示
NOIP 2006 提高组 第一题
思路
很像石子合并的一道题,只不过把获得的价值给改了一下。
如果有两堆石子可以合并,分别为 ( i , k ) , ( k + 1, j ) ,获得的价值为 head [ i ] * tail [ k ] * tail [ j ]。
然后像石子合并那样做就可以了。
CODE
#include < bits/stdc++.h >
#define dbg( x ) cout << #x << " = " << x << endl
#define eps 1 e - 8
#define pi acos( - 1.0 )
using namespace std ;
typedef long long LL ;
const int inf = 0x 3f3f3f3f ;
template < class T > inline void read(T & res )
{
char c ;T flag = 1 ;
while((c = getchar()) < ' 0 ' ||c > ' 9 ' )if(c == ' - ' )flag =- 1 ;res =c - ' 0 ' ;
while((c = getchar()) >= ' 0 ' &&c <= ' 9 ' )res =res * 10 +c - ' 0 ' ;res *=flag ;
}
namespace _buff {
const size_t BUFF = 1 << 19 ;
char ibuf [BUFF ], *ib = ibuf , *ie = ibuf ;
char getc() {
if (ib == ie ) {
ib = ibuf ;
ie = ibuf + fread(ibuf , 1 , BUFF , stdin );
}
return ib == ie ? - 1 : *ib ++ ;
}
}
int qread() {
using namespace _buff ;
int ret = 0 ;
bool pos = true ;
char c = getc();
for (; (c < ' 0 ' || c > ' 9 ' ) && c != ' - ' ; c = getc()) {
assert( ~c );
}
if (c == ' - ' ) {
pos = false ;
c = getc();
}
for (; c >= ' 0 ' && c <= ' 9 ' ; c = getc()) {
ret = (ret << 3 ) + (ret << 1 ) + (c ^ 48 );
}
return pos ? ret : -ret ;
}
const int maxn = 307 ;
int n ;
int head [maxn ];
int tail [maxn ];
int f [maxn ][maxn ];
int main()
{
read(n );
for ( int i = 1 ; i <= n ; ++i ) {
read( head [i ]);
head [n + i ] = head [i ];
}
for ( int i = 1 ; i <= 2 * n - 1 ; ++i ) {
tail [i ] = head [i + 1 ];
}
int ans = - 1 ;
tail [ 2 * n ] = head [ 1 ];
for ( int z = 1 ; z <= n - 1 ; ++z ) { //!枚举区间长度
for ( int i = 1 ; i <= 2 * n - z ; ++i ) {
int j = i + z ;
for ( int k = i ; k <= j - 1 ; ++k ) {
f [i ][j ] = max( f [i ][j ], f [i ][k ] + f [k + 1 ][j ] + head [i ] * tail [k ] * tail [j ]);
ans = max(ans , f [i ][j ]);
}
}
}
cout << ans << endl ;
return 0 ;
}