码迷,mamicode.com
首页 > 其他好文 > 详细

HDU4283 You Are the One(经典区间dp)

时间:2020-02-18 20:34:31      阅读:73      评论:0      收藏:0      [点我收藏+]

标签:图片   ace   div   就是   play   you   mes   none   之间   

动态规划要从最优子结构来推出大的方案

对于本题,我们要思考,什么是大的,什么是小的。

或许有些人会想设计状态为f[i],表示我从1-i的最小花费,但是仅仅这样是不够的,因为在这之间进小黑屋的不一定要在这之间就出来,他有后效性

那么什么是没有后效性的呢,如果我们判定这个区间就是全部的大小,他没有后面还在排队了,那么这就不会产生后效影响了

所以我们对这个方程进行改换定义,定义他为f[i][j],也就是我从i-j的最小花费且不算他前面的数,也就是我每个区间都是从第一个开始的,这样就不会被别的影响了,

那我们想我们如何转移方程呢?

在我们的对状态定义之后,不难发现要用区间dp

那么f[l][r]=min(a[i]*(k-1)+f[i+1][i+k-1]+f[i+k][j]+k*(sum[j]-sum[i+k-1]))

他的意思是我第l个数我第几个走,我们发现.f[i+1][i+k-1],f[i+k][j]这两个区间都是计算过的,且题目告诉我们先进的最后出来,这样就完美的符合转移的关系

技术图片
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
int dp[102][102];
int a[105];
int sum[105];
int main(){
    int t;
    cin>>t;
    int cas=0;
    while(t--){
        cas++;
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        cin>>a[i];
        for(int i=1;i<=n;i++)
        sum[i]=sum[i-1]+a[i];
        int len=1;
        int i,j,k;
        for(i=1;i<n;i++){
            for(j=i+1;j<=n;j++)
            dp[i][j]=inf;
        }
        for(len=1;len<=n;len++){
            for(i=1;i+len-1<=n;i++){
                j=len+i-1;
                for(k=1;k<=len;k++){
                    dp[i][j]=min(dp[i][j],a[i]*(k-1)+dp[i+1][i+k-1]+dp[i+k][j]+k*(sum[j]-sum[i+k-1]));
                }
            }
        }
        printf("Case #%d: %d\n",cas,dp[1][n]);
    }
    return 0;
}
View Code

 

HDU4283 You Are the One(经典区间dp)

标签:图片   ace   div   就是   play   you   mes   none   之间   

原文地址:https://www.cnblogs.com/ctyakwf/p/12327494.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!