HDU 4283 You Are the One(区间DP)
2016-08-15 19:56
435 查看
题目:You Are the One
题意:
n个男孩排成队登台,每个男孩有一个屌丝值Di
若某男孩第k个登台 ,他将产生Di*(k-1)的愤怒值
要求所有男孩愤怒值最小
可以做的操作是将男孩丢进栈里面改变登台顺序(栈满足先进后出 )
分析:
dp[i][j]表示区间[i,j]所有男孩的最小愤怒值
if (i == j) return 0;//第一个登台愤怒值为0
状态转移:
首先明确的是区间[i,j]内共有j-i+1个人 (只考虑这j-i+1个人)
当从区间[i+1,j]到 区间[i,j],加入了第i个人
考虑第i个人第几个登台,假设他第k个登台
原本在[i,j]区间里面,他应该第一个登台
现在第k个登台,表示他后面k-1个人先于他登台(因为栈的特性)
所以现在顺序是[i+1,(i+1)+(k-1)-1]登台,i第k个登台,
后面的[(i+1)+(k-1),j]再登台
但是状态转移并不是dp[i+1][(i+1)+(k-1)-1]+a[i]*(k-1)+dp[(i+1)+(k-1)][j]
因为dp[(i+1)+(k-1)][j]是指这些人按从1开始的顺序登台
而实际上后面区间[(i+1)+(k-1),j]的登台是从k+1到(j-i+1)的顺序
其实只需再加上 k*∑a[l] ((i+1)+(k-1) <= l <= j)
也就是说,区间 [(i+1)+(k-1),j]里面每个人的登台都往后推了k位
所以最后的状态转移方程是:dp[i][j] = min
dp[i+1][(i+1)+(k-1)-1]+a[i]*(k-1)+dp[(i+1)+(k-1)][j] + k * sum[(i+1)+(k-1)][j]
其中sum[l][r]表示区间[l,r]的人的屌丝值之和
题意:
n个男孩排成队登台,每个男孩有一个屌丝值Di
若某男孩第k个登台 ,他将产生Di*(k-1)的愤怒值
要求所有男孩愤怒值最小
可以做的操作是将男孩丢进栈里面改变登台顺序(栈满足先进后出 )
分析:
dp[i][j]表示区间[i,j]所有男孩的最小愤怒值
if (i == j) return 0;//第一个登台愤怒值为0
状态转移:
首先明确的是区间[i,j]内共有j-i+1个人 (只考虑这j-i+1个人)
当从区间[i+1,j]到 区间[i,j],加入了第i个人
考虑第i个人第几个登台,假设他第k个登台
原本在[i,j]区间里面,他应该第一个登台
现在第k个登台,表示他后面k-1个人先于他登台(因为栈的特性)
所以现在顺序是[i+1,(i+1)+(k-1)-1]登台,i第k个登台,
后面的[(i+1)+(k-1),j]再登台
但是状态转移并不是dp[i+1][(i+1)+(k-1)-1]+a[i]*(k-1)+dp[(i+1)+(k-1)][j]
因为dp[(i+1)+(k-1)][j]是指这些人按从1开始的顺序登台
而实际上后面区间[(i+1)+(k-1),j]的登台是从k+1到(j-i+1)的顺序
其实只需再加上 k*∑a[l] ((i+1)+(k-1) <= l <= j)
也就是说,区间 [(i+1)+(k-1),j]里面每个人的登台都往后推了k位
所以最后的状态转移方程是:dp[i][j] = min
dp[i+1][(i+1)+(k-1)-1]+a[i]*(k-1)+dp[(i+1)+(k-1)][j] + k * sum[(i+1)+(k-1)][j]
其中sum[l][r]表示区间[l,r]的人的屌丝值之和
#define mem(a,x) memset(a,x,sizeof(a)) #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<set> #include<stack> #include<cmath> #include<map> #include<stdlib.h> #include<cctype> #include<string> #define Sint(n) scanf("%d",&n) #define Sll(n) scanf("%I64d",&n) #define Schar(n) scanf("%c",&n) #define Sint2(x,y) scanf("%d %d",&x,&y) #define Sll2(x,y) scanf("%I64d %I64d",&x,&y) #define Pint(x) printf("%d",x) #define Pllc(x,c) printf("%I64d%c",x,c) #define Pintc(x,c) printf("%d%c",x,c) using namespace std; typedef long long ll; /* 题意: n个男孩排成队登台,每个男孩有一个屌丝值Di 若某男孩第k个登台 ,他将产生Di*(k-1)的愤怒值 要求所有男孩愤怒值最小 可以做的操作是将男孩丢进栈里面改变登台顺序(栈满足先进后出 ) 分析: dp[i][j]表示区间[i,j]所有男孩的最小愤怒值 if (i == j) return 0;//第一个登台愤怒值为0 状态转移: 首先明确的是区间[i,j]内共有j-i+1个人 (只考虑这j-i+1个人) 当从区间[i+1,j]到 区间[i,j],加入了第i个人 考虑第i个人第几个登台,假设他第k个登台 原本在[i,j]区间里面,他应该第一个登台 现在第k个登台,表示他后面k-1个人先于他登台(因为栈的特性) 所以现在顺序是[i+1,(i+1)+(k-1)-1]登台,i第k个登台, 后面的[(i+1)+(k-1),j]再登台 但是状态转移并不是dp[i+1][(i+1)+(k-1)-1]+a[i]*(k-1)+dp[(i+1)+(k-1)][j] 因为dp[(i+1)+(k-1)][j]是指这些人按从1开始的顺序登台 而实际上后面区间[(i+1)+(k-1),j]的登台是从k+1到(j-i+1)的顺序 其实只需再加上 k*∑a[l] ((i+1)+(k-1) <= l <= j) 也就是说,区间 [(i+1)+(k-1),j]里面每个人的登台都往后推了k位 所以最后的状态转移方程是:dp[i][j] = min dp[i+1][(i+1)+(k-1)-1]+a[i]*(k-1)+dp[(i+1)+(k-1)][j] + k * sum[(i+1)+(k-1)][j] 其中sum[l][r]表示区间[l,r]的人的屌丝值之和 */ const int N = 111; int dp ; int sum ;//其实一维数组也可以就不用二维数组了sum[r] - sum[l-1]代替sum[l][r] int a ; int DP(int i,int j) { if (i >= j) return 0; if (~dp[i][j]) return dp[i][j]; //枚举第i个人的登台顺序 dp[i][j] = DP(i+1,j) + a[i]*((j-i+1)-1);//最后一个登台 for (int k = 1;k < j-i+1;++k) { int mid = (i+1)+(k-1)-1; dp[i][j] = min(dp[i][j],DP(i+1,mid)+a[i]*(k-1)+DP(mid+1,j)+k*(sum[j]-sum[mid])) ; } return dp[i][j]; } int main() { int T;Sint(T);int kas = 0; while (T--) { int n;Sint(n); for (int i = 1;i <= n;++i) { Sint(a[i]); sum[i] = sum[i-1]+a[i]; } mem(dp,-1); printf("Case #%d: %d\n",++kas,DP(1,n)); } return 0; }
相关文章推荐
- HDU-4283 You Are the One 区间DP
- hdu 4283 You Are the One 区间dp
- HDU 4283 You Are the One (区间DP)
- HDU 4283 - You Are the One(区间DP)
- HDU --4283--You Are the One--区间DP
- HDU 4283 You Are the One(12年天津 区间DP)
- HDU 4283 You Are the One(区间DP)
- HDU 4283 You Are the One(区间DP)
- hdu 4283 You Are the One(区间dp)
- HDU 4283 You Are the One ★(进出栈的括号匹配性质:区间DP)
- HDU 4283 You Are the One (区间DP)
- HDU 4283 You Are the One ★(进出栈的括号匹配性质:区间DP)
- HDU 4283 You Are the One 区间dp
- HDU 4283 You Are the One(区间dp)
- hdu 4283 You Are the One(区间dp)
- Hdu 4283 You Are the One(区间dp)
- HDU 4283 You Are the One [区间DP]
- HDU 4283 You Are the One(区间dp)
- HDU 4283 You Are the One(区间dp)
- HDU 4283 You are the one(区间DP)