zoukankan      html  css  js  c++  java
  • POJ 2671 Jimmy's Bad Day ★ (区间DP)

    题目大意:一个圆圈中有很多n个点(包括起点),其中除了起点外其他点除都有需要送的包裹。现在已经迟到了,而每到一个点处送了包裹都要因为迟到而每迟到1min扣和包裹数相同的钱。给定n和每个点的包裹数还有前一个点到下一个点的时间(来回一样),求最少需要赔的钱。   一类折线问题的DP --- 以某个点位中心,不断扩展两边折返,形成区间更新 clock_time[i]0到i点时间。顺时针 anti_clock_time[i]i到0点时间。逆时针 w[i][j]i到j有的包裹总数。 l[i][j]表示站在i处要处理i到j最少需要赔的钱 r[i][j]表示站在j处要处理i到j最少需要赔的钱 POJ 2671 方程图解   现在来分析l[i][j](r[i][j]同理),即站在i处要处理i到j最少需要赔的钱,那么可以有两种情况:①先走到i+1,此时就变成了l[i+1][j],又因为先走了time[i]的时间(从i到i+1),所以i+1到j的处理时间都要推迟time[i],所以l[i][j] = min(l[i][j], l[i+1][j] + time[i]*w[i+1][j]);②先从外侧走到j,然后就是r[i+1][j],而此时先花掉的时间就是clock_time[i] + anti_clock_time[j](#),所以l[i][j] = min(l[i][j], r[i+1][j] + (#)*w[i+1][j])。 POJ 2671 转移方程图解 而最终的状态就是l\r[0][n-1] or l\r[1][0],但因为[1][0]表示不方便,所以我们在0..n-1的基础上增加一个n来表示0,这样l\r[1][0]就能表示成l\r[1][n],然后再综合一下,结果就是min(l[0][n], r[0][n])~~~(代码中因为n自增了1,所以那儿是[0][n-1])   代码:  
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #define MID(x,y) ((x+y)>>1)
    using namespace std;
    typedef long long LL;
    
    const int sup = 1000000000;
    const int N = 310;
    int l[N][N], r[N][N], w[N][N];
    int clock_time[N];
    int anti_clock_time[N];
    int time[N], num[N];
    void init(int n){
        clock_time[0] = 0;
        for (int i = 1; i < N; i ++){
            clock_time[i] = clock_time[i-1] + time[i-1];
        }
        anti_clock_time[n] = 0;
        for (int i = n - 1; i >= 0; i --){
            anti_clock_time[i] = anti_clock_time[i+1] + time[i];
        }
        for (int i = 0; i < n; i ++){
            w[i][i] = num[i];
            for (int j = i + 1; j < n; j ++)
                w[i][j] = w[i][j-1] + num[j];
        }
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < n; j ++){
                if (i == j){
                    l[i][j] = 0;
                    r[i][j] = 0;
                }
                else{
                    l[i][j] = sup;
                    r[i][j] = sup;
                }
            }
        return ;
    }
    int main(){
        int n;
        while(scanf("%d", &n) == 1){
            if (n == 0)
                break;
            for (int i = 0; i < n; i ++)
                scanf("%d%d", &num[i], &time[i]);
            num[n] = time[n] = 0;
            n ++;
            init(n);
            for (int k = 1; k < n; k ++){
                for (int i = 0; i + k < n; i ++){
                    int j = i + k;
                    l[i][j] = min(l[i+1][j] + time[i] * w[i+1][j], r[i+1][j] + (clock_time[i] + anti_clock_time[j]) * w[i+1][j]);
                    r[i][j] = min(r[i][j-1] + time[j-1] * w[i][j-1], l[i][j-1] + (clock_time[i] + anti_clock_time[j]) * w[i][j-1]);
                }
            }
            printf("%d\n", min(l[0][n-1], r[0][n-1]));
        }
    	return 0;
    }
    
     
    举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG
  • 相关阅读:
    JDK1.8HashMap底层实现原理
    关于map转json,空key丢失的问题
    spring一些注解的使用及相关注解差异
    搭建基础项目遇到的一些小坑
    解析ftp上word文档的文字并输入
    R语言中回归模型预测的不同类型置信区间应用比较分析
    R语言中的广义线性模型(GLM)和广义相加模型(GAM):多元(平滑)回归分析保险资金投资组合信用风险敞口
    R语言对巨灾风险下的再保险合同定价研究案例:广义线性模型和帕累托分布Pareto distributions分析
    R语言中GLM(广义线性模型),非线性和异方差可视化分析
    如何用R语言绘制生成正态分布图表
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/4114009.html
Copyright © 2011-2022 走看看