POJ 1651
思路:动态规划,不论怎么取则必须有一个最后取(设为k),设dp[n][m] 是n到m这段中的最优解,则dp[n][m] = min(dp[n][k]+dp[k][m]+a[k]*a[n]*a[m],dp[n][m])(k > n && k < m),需要记忆化搜索(即,一旦dp[n][m]已被搜到过直接返回),通过递归求解下一状态,再回溯到当前最优解。
#include<iostream> #include<cstdio> #include<string> #include<cstring> #define MAXN 111 #define INF 0x7fffffff #define LL long long using namespace std; LL dp[MAXN][MAXN]; int a[MAXN]; LL dfs(int n,int m){ if(dp[n][m] != INF) return dp[n][m]; if(n == m-2) return dp[n][m] = a[n]*a[n+1]*a[n+2]; if(n == m-1) return dp[n][m] = 0; for(int i = n+1;i <= m-1;i ++) dp[n][m] = min(dfs(n,i)+dfs(i,m)+a[i]*a[n]*a[m],dp[n][m]); return dp[n][m]; } int main(){ int n; while(~scanf("%d",&n)){ for(int i = 0;i < n;i ++) for(int j = 0;j < n;j ++) dp[i][j] = INF; for(int i = 0;i < n;i ++) scanf("%d",a+i); printf("%lld\n",dfs(0,n-1)); } return 0; }