1. 程式人生 > >【CH 5301】石子歸併【DP】

【CH 5301】石子歸併【DP】

題目大意:

思路:

這道題不能合併兩堆不相鄰的石子,所以堆和佇列就肯定不行了。考慮DP。
f[i][j]為合併第i堆到第j堆得最下代價,那麼由於肯定得將它們分成兩堆來合併,那麼就再在ij之間列舉個k,那麼久可以得到方程:

f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+sum[j]sum[i1])
其中sum表示字首和。
最終答案為f[1][n]

程式碼:

#include <cstdio>
#include <cstring> #include <algorithm> using namespace std; int n,sum[301],f[301][301]; int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&sum[i]); sum[i]+=sum[i-1]; //求字首和 } memset(f,0x3f3f3f3f,sizeof(f)); for (int i=n;i>=1
;i--) { f[i][i]=0; for (int j=i+1;j<=n;j++) for (int k=i;k<=j;k++) f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+sum[j]-sum[i-1]); } printf("%d\n",f[1][n]); return 0; }