这道题把老师坑了好久(⊙_⊙),后来老师讲了前缀和.......
假设ans为每一次消耗的体力:
ans[i][j]=ans[i]-ans[j]+1。
ans[i]=ans[i-1]+a[i]。
ans[j]就不用再算一遍了........
动态转移方程:dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+ans[j]-ans[i-1])。
代码:
#include<iostream> #include<algorithm> #include<cstring> #include<cmath> using namespace std; int n; int dp[1100][1100],a[11000]; int ans[10000]; int main() { cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; } for(int i=1;i<=n;i++) { ans[i]=ans[i-1]+a[i];//前缀和 } for(int t=1;t<n;t++)//算差值 { for(int i=1;i+t<=n;i++) { int j=i+t; dp[i][j]=2147483647;//赋值 for(int k=i;k<j;k++) { dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+ans[j]-ans[i-1]);//直接套 } } } cout<<dp[1][n];//输出 }
老师也被套进去了,QwQ.................