NYOJ 737 stone Merge (1) (interval DP + parallelogram optimization)
Defining the state dp [I] [j] is the minimum price for merging from the I stone to the j stone.
The unoptimized code is as follows: it takes 248 ms.
#include
#include
#include
#include
#include #include
#include
#include
#include
using namespace std;#define LL long long#define pi acos(-1.0)//#pragma comment(linker, "/STACK:1024000000")const int mod=1e9+7;const int INF=0x3f3f3f3f;const double eqs=1e-3;const int MAXN=40000+10;int dp[300][300], sum[300];int main(){ int n, i, j, k, len, x; while(scanf("%d",&n)!=EOF) { sum[0]=0; memset(dp,INF,sizeof(dp)); for(i=1; i<=n; i++) { scanf("%d",&x); sum[i]=sum[i-1]+x; dp[i][i]=0; } for(len=2; len<=n; len++) { for(i=1; i<=n-len+1; i++) { j=i+len-1; for(k=i+1; k<=j; k++) { dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k][j]+sum[j]-sum[i-1]); } } } printf("%d\n",dp[1][n]); } return 0;}
Then, we can use a four-sided inequality to optimize the problem. by recording the optimal split point of s [I] [j] as k, we can optimize n ^ 3 to n ^ 2.
The optimization code is as follows: it takes 36 ms ....
#include
#include
#include
#include
#include #include
#include
#include
#include
using namespace std;#define LL long long#define pi acos(-1.0)//#pragma comment(linker, "/STACK:1024000000")const int mod=1e9+7;const int INF=0x3f3f3f3f;const double eqs=1e-3;const int MAXN=40000+10;int dp[300][300], sum[300], s[300][300];int main(){ int n, i, j, k, len, x; while(scanf("%d",&n)!=EOF){ sum[0]=0; memset(dp,INF,sizeof(dp)); for(i=1;i<=n;i++){ scanf("%d",&x); sum[i]=sum[i-1]+x; dp[i][i]=0; s[i][i]=i; } for(len=2;len<=n;len++){ for(i=1;i<=n-len+1;i++){ j=i+len-1; for(k=s[i][j-1];k<=s[i+1][j];k++){ if(dp[i][j]>dp[i][k-1]+dp[k][j]+sum[j]-sum[i-1]){ dp[i][j]=dp[i][k-1]+dp[k][j]+sum[j]-sum[i-1]; s[i][j]=k; } } } } printf("%d\n",dp[1][n]); } return 0;}