• CSUOJ 1141——第四届河南省程序设计大赛


    题目的意思是给你一个机器人,初始的时候在某一个给定的路灯位置,机器人要把路边所有的路灯关掉,每个路灯都有一个距离和一个功率,求要把所有的路灯关掉最小的最终能耗是多少?

    题目是一个很明显的区间DP。可以这样考虑,机器人关掉一个区间的路灯后,一定停留在该区间的最左端或者最右端,而且必须包括起点,显然。

    这样我们就可以区间dp了。

    对于每一个含有初始位置的区间[i,j],只有两种位置使其最终的位置为j,那就是i和j-1。这样就得到了状态转移了。

    接下来还有一个问题,就是怎么计算能耗呢?这样想,对于每个状态,表示关闭该区间的所有的灯后根据其所停留的位置,所有路灯的最小能耗总和。

    所以我们可以对于每个路灯,用一个数组表示前面n个路灯的功耗总和,这样就可以dp了。

    上代码:(效率还挺高的)

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #define maxn 1010
     5 using namespace std;
     6  
     7 int f[2][maxn][maxn],w[maxn],d[maxn],n,k,tep,tep1,tep2;
     8  
     9 int main()
    10 {
    11     while (scanf("%d",&n)!=EOF)
    12     {
    13         scanf("%d",&k);
    14         for (int i=1; i<=n; i++) scanf("%d%d",&d[i],&w[i]),w[i]+=w[i-1];
    15         memset(f,0x3f,sizeof f);
    16         f[1][k][k]=f[0][k][k]=0;
    17         for (int i=k; i>0; i--)
    18             for (int j=k; j<=n; j++)
    19             {
    20                 if (i==j) continue;
    21                 tep=w[n]-w[j]+w[i];
    22                 tep1=tep*(d[i+1]-d[i])+f[0][i+1][j];
    23                 tep2=tep*(d[j]-d[i])+f[1][i+1][j];
    24                 f[0][i][j]=min(tep1,tep2);
    25                 tep=w[n]-w[j-1]+w[i-1];
    26                 tep1=tep*(d[j]-d[j-1])+f[1][i][j-1];
    27                 tep2=tep*(d[j]-d[i])+f[0][i][j-1];
    28                 f[1][i][j]=min(tep1,tep2);
    29             }
    30         printf("%d
    ",min(f[0][1][n],f[1][1][n]));
    31     }
    32     return 0;
    33 }
    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    在 Laravel 5.1 中使用 Pjax
    在 iOS 中实现方法链调用
    利用 WireShark 深入调试网络请求
    设计一个健壮的后台下载
    设计一个健壮的大型文件下载系统
    iOS开发基础知识:Core Animation(核心动画)
    开发 Swift 和 Objective-C 混编的 Framework
    protobuf3 iOS 接入 protobuf
    iOS之ProtocolBuffer搭建
    iOS10 推送必看(基础篇)
  • 原文地址:https://www.cnblogs.com/lochan/p/3364091.html
Copyright © 2020-2023  润新知