HDU4283(区间dp)
作者:互联网
题目大意:一些屌丝排队进场,第k个进场的人后又k-1*a[i]的愤怒值,为了得到最小的愤怒值,可以利用一个栈来调整顺序,第i个人进栈可以让第i+1个人先行入场,对于栈里的元素必须是后进先出,问如何合理利用栈来以得到最小的愤怒值。
解题思路:我们用dp[i][j]表示区间i~j之中的元素可得到的最小的愤怒值。对于i~j中的元素i我们然他第k个入场,那么其后面的k-1个元素就要先行入场,
这是问题就变成了dp[i+1][i+k-1]和dp[i+k][j], 对于第i个元素的愤怒值为:(k-1)*a[i],而第i+k~j的愤怒值要加上k*(sum[j]-sum[i+1-1]);
最后dp[1][n]就是答案
以上摘自https://blog.csdn.net/lvshubao1314/article/details/44672559
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define inf 0x3f3f3f3f
using namespace std;
int s[105],sum[105];
int dp[105][105];
int main()
{
//freopen("t.txt","r",stdin);
int T,n;
scanf("%d",&T);
for(int ca=1;ca<=T;ca++)
{
printf("Case #%d: ",ca);
scanf("%d",&n);
//cout<<n<<"*"<<endl;
int p=0;
for(int i=0;i<n;i++)
{
scanf("%d",&s[i]);
//cout<<s[i]<<endl;
sum[i]=s[i]+p;
p=sum[i];
}
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
dp[i][j]=inf;
}
}
for(int t=1;t<n;t++)
{
for(int i=0;i+t<n;i++)
{
int j=i+t;
for(int k=i;k<=j;k++)
{
dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]+(k-i)*s[i]+(k-i+1)*(sum[j]-sum[k]));
}
}
}
printf("%d\n",dp[0][n-1]);
}
return 0;
}
标签:HDU4283,int,sum,区间,include,愤怒,dp,105 来源: https://blog.csdn.net/qq_39861441/article/details/88591264