zoukankan      html  css  js  c++  java
  • Tyvj1098

    题目链接

    分析:
    Tyvj上的题,描述都很清奇,
    就像这道题,我怎么都觉得样例不对。。。

    这道题有一个限制:顺序不得改变
    很显然这是一道区间dp
    区间(i,j)的费用是:(T[j]+S)*(F[j]-F[i-1])
    这个S很不好搞啊,我们不知道之前我们分了多少组

    T[i]表示1~i的时间和
    F[i]表示i~n的费用和
    在这里我们实际上用的是倒推:
    f[i]表示对于从i到n的任务安排的最优解。
    则有:f[i]=min{f[j]+(S+T[i]-T[j])*F[i]} (i < j <= n+1)

    怎么理解这个 (S+T[i]-T[j])*F[i]呢
    我们把柿子展开看看:
    假设划分成三个部分(1~2,3~3,4~5),g[i]表示单个任务所需时间

    花费
    =(S+T[2]) * (g[1]+g[2])
    +(S+S+T[3]-T[2]) * (g[3])
    +(S+S+S+T[5]-T[3]) * (g[4]+g[5])

    化简得:
    =S * g[1]+S * g[2]+S * g[3]+S * g[3]+S * g[4]+S * g[4]+S * g[4]+S * g[5]+S * g[5]+S * g[5]
    +T[2] * g[1]+T[2] * g[2]-T[2] * g[3]+T[3] * g[3]+T[5] * g[4]-T[3] * g[4]+T[5] * g[5]-T[3] * g[5]

    继续化简:
    =S * (g[1]+g[2]+g[3]+g[4]+g[5])
    +S * (g[3]+g[4]+g[5])
    +S * (g[4]+g[5])
    +T[2] * (g[1]+g[2])
    +(T[3]-T[2]) * g[3]
    +(T[5]-T[3])* (g[4]+g[5])

    继续:
    =(S+T[2]) * (g[1]+g[2]+g[3]+g[4]+g[5])
    +(S +T[3]-T[2])* (g[3]+g[4]+g[5])
    +(S+T[5]-T[3]) * (g[4]+g[5])

    这就是状态转移中的柿子啦:
    这里写图片描述

    这里写代码片
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    
    using namespace std;
    
    const int N=5010;
    int T[N],F[N],f[N];
    int n,S;
    
    void doit()
    {
        int i,j;
        for (i=n;i>=1;i--) F[i]=F[i+1]+F[i];
        memset(f,0x7f,sizeof(f));
        f[0]=0;
        for (i=1;i<=n;i++)
            for (j=1;j<=i;j++)
            {
                int t=(T[i]-T[j-1]+S)*F[j];
                f[i]=min(f[i],f[j-1]+t);
            }
        printf("%d",f[n]);
    }
    
    int main()
    {
        scanf("%d%d",&n,&S);
        for (int i=1;i<=n;i++) scanf("%d%d",&T[i],&F[i]),T[i]=T[i-1]+T[i];
        doit();
        return 0;
    }
  • 相关阅读:
    微信小程序从零开始开发步骤(三)
    微信小程序从零开始开发步骤(三)底部导航栏
    微信小程序从零开始开发步骤(二)
    微信小程序从零开始开发步骤(二)
    微信小程序从零开始开发步骤(一)
    [NOIP2016]组合数问题
    5.20 考试 20 未完
    lca 例题 WK
    rmq RMQ
    BZ
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673247.html
Copyright © 2011-2022 走看看