Eat Walnuts(区间DP)

题目连接:https://ac.nowcoder.com/acm/contest/8688/E
博客园食用链接:https://www.cnblogs.com/lonely-wind-/p/13907406.html

As we all know, in the ACM ICPC held in 2017, the organizer of Xinjiang University presented a box of walnuts to each coach. Our coach is happy to share with the team members except Mr.Watermelon. He is going to test Mr.Watermelon with a game when Mr.Watermelon want to eat some walnuts.

He put some walnuts in a row and let Mr.Watermelon pick one of them. And this walnut is not the first or last in the queue. The price Mr.Watermelon need to pay is : the walnut, the walnut in front of the walnut, and the walnut behind the walnut , the square of the sum of the size of these three walnuts.

For example, now there is a row of walnuts in front of Mr.Watermelon. Their size is: 3 1 50 20 15. If this time Mr.Watermelon picked the third walnut. He needs to pay (1 + 50 + 20) ∗ (1 + 50 + 20) = 5041.

After a walnut is taken away, it will leave the queue. Then Mr.Watermelon picks a walnut again until only two walnuts remain in the queue.

Mr.Watermelon wants to know what the minimum price he will pay when he takes walnuts until there are only two walnuts in the queue. But he needs more time to spend with his girlfriend. So he ask you to help him calculate this problem.

输入描述:

Input contains multiple test cases.The first line of each test case contains a integer n(3 ≤ n ≤ 100), the number of walnuts at the beginning. The second line contains n positive integers separated by spaces, representing the size of each walnut. Each positive integer does not exceed 1,000.

For 50% of the testcases, n ≤ 50.

For 90% of the testcases, n ≤ 90.

For 100% of the testcases, n ≤ 100.

The number of the testcases does not exceed 1000.

输出描述:

For each test case, print a integer–the minimum price Mr.Watermelon will pay.

示例1
输入
5
3 1 50 20 15

输出
6698

题目大意:给你n件商品,你不能够买第一件和最后一件,而你买第i个商品的代价是 ( a i + a i + 1 + a i − 1 ) 2 (a_i+a_{i+1}+a_{i-1})^2 (ai+ai+1+ai1)2,问最后买光所有商品的最小代价是多少

emmm,本来可以一发AC的。。。结果inf开小了QAQ。一看这玩意儿就知道是个区间DP,那么于是三连for上头,枚举长度,枚举起点,枚举终点,由于第一件和最后一件不能买,所以有:

for (int len=2; len<=n-2; len++){//由于2个买不了,所以长度只有n-2
	for (int st=2; st+len-1<=n-1; st++){//对2-n-1进行区间DP
		int ed=st+len-1; 
		for (int k=st; k<=ed; k++){
			.....
		}
	}
}

那么DP的转移方程怎么写呢,其实之前博客里面有一题杀狼的题目也是相同的道理https://www.cnblogs.com/lonely-wind-/p/13264259.html
我们枚举中间的保留点,那么就可以得到其方程:
d p [ i ] [ j ] = m i n ( d p [ i ] [ j ] , d p [ i ] [ k − 1 ] + d p [ k + 1 ] [ j ] + ( a [ k ] + a [ i − 1 ] + a [ j + 1 ] ) 2 ) dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+(a[k]+a[i-1]+a[j+1])^2) dp[i][j]=min(dp[i][j],dp[i][k1]+dp[k+1][j]+(a[k]+a[i1]+a[j+1])2)

#include <bits/stdc++.h>
using namespace std;

const int mac=120;
const int inf=5e8+10;

int a[mac],dp[mac][mac];

int pw(int x){return x*x;}

int main(int argc, char const *argv[])
{
	int n;
	while (~scanf ("%d",&n)){
		for (int i=1; i<=n; i++)
			scanf ("%d",&a[i]);
		for (int i=1; i<=n; i++)
			for (int j=i; j<=n; j++)
				dp[i][j]=inf;
		for (int i=2; i<n; i++) dp[i][i]=pw(a[i]+a[i-1]+a[i+1]);
		for (int len=2; len<=n-2; len++){
			for (int st=2; st+len-1<=n-1; st++){
				int ed=st+len-1; 
				for (int k=st; k<=ed; k++){
					dp[st][ed]=min(dp[st][ed],dp[st][k-1]+dp[k+1][ed]+pw(a[k]+a[st-1]+a[ed+1]));
				}
			}
		}
		printf ("%d\n",dp[2][n-1]);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值