hdu4283
分析
这微博主写得很清楚了:http://blog.csdn.net/u014141559/article/details/38035603?utm_source=tuicool&utm_medium=referral
关键就是要想到,这个栈可以类比区间,而且还真的是,能想到挺厉害的,这里也是开拓了思路。
题目
http://acm.hdu.edu.cn/showproblem.php?pid=4283
代码
递推
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
int dp[110][110];
int sum[110];
int a[110];
int main()
{
int T;
int kase=1;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
sum[0]=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
for(int i=1; i<=n; i++)
{
for(int j=i+1; j<=n; j++)
dp[i][j]=0x3f3f3f3f;
}
for(int p=1; p<=n; p++)
{
for(int i=1; i<=n-p+1; i++)
{
int j=i+p-1;
for(int k=1; k<=p; k++)
{
dp[i][j]=min(dp[i][j],dp[i+1][i+k-1]+dp[i+k][j]+(k-1)*a[i]+(sum[j]-sum[i+k-1])*k);
}
}
}
printf("Case #%d: %d\n",kase++,dp[1][n]);
}
}
记忆优化:
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
int dp[110][110];
int sum[110];
int a[110];
int solve(int i,int j)
{
if(dp[i][j]!=-1) return dp[i][j];
if(i>=j) return 0;
dp[i][j]=0x3f3f3f3f;
for(int k=1;k<=j-i+1;k++)
{
dp[i][j]=min(dp[i][j],solve(i+1,i+k-1)+solve(i+k,j)+a[i]*(k-1)+(sum[j]+sum[i+k-1])*k);
}
return dp[i][j];
}
int main()
{
int T;
int kase=1;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
sum[0]=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
memset(dp,-1,sizeof(dp));
printf("Case #%d: %d\n",kase++,solve(1,n));
}
}