poj 1651 区间dp
题意:给出一组N个数,每次从中抽出一个数(第一和最后一个不能抽),该次的得分即为抽出的数与相邻两个数的乘积。直到只剩下首尾两个数为止。问最小得分是多少?
链接:点我
转移方程:
dp[i][j]=dp[i][k]+dp[k][j]+a[i]*a[j]*a[k]
这里的k一定是最后一步算的,所以乘以a[i]和a[j]
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x3f3f3f3f; 11 const double eps=1e-5; 12 typedef long long ll; 13 #define cl(a) memset(a,0,sizeof(a)) 14 #define ts printf("*****\n"); 15 const int MAXN=1005; 16 int n,m,tt; 17 int a[MAXN],dp[MAXN][MAXN]; 18 int main() 19 { 20 int i,j,k; 21 #ifndef ONLINE_JUDGE 22 freopen("1.in","r",stdin); 23 #endif 24 while(scanf("%d",&n)!=EOF) 25 { 26 for(i=0;i<n;i++) 27 { 28 scanf("%d",a+i); 29 } 30 cl(dp); 31 for(i=0;i<n;i++) 32 for(j=i+2;j<n;j++) dp[i][j]=INF; 33 for(i=0;i<n-2;i++) 34 { 35 dp[i][i+2]=a[i]*a[i+1]*a[i+2]; 36 } 37 for(int len=3;len<n;len++) 38 { 39 for(i=0;i+len<n;i++) 40 { 41 j=len+i; 42 for(k=i+1;k<=j-1;k++) 43 { 44 dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+a[i]*a[j]*a[k]); 45 } 46 } 47 } 48 printf("%d\n",dp[0][n-1]); 49 } 50 }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步