zoukankan      html  css  js  c++  java
  • 关路灯

    洛咕

    题意:某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少)。老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯。为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电。他每天都是在天亮时首先关掉自己所处位置的路灯,然后可以向左也可以向右去关灯。开始他以为先算一下左边路灯的总功率再算一下右边路灯的总功率,然后选择先关掉功率大的一边,再回过头来关掉另一边的路灯,而事实并非如此,因为在关的过程中适当地调头有可能会更省一些。现在已知老张走的速度为1m/s,每个路灯的位置(是一个整数,即距路线起点的距离,单位:m)、功率(W),老张关灯所用的时间很短而可以忽略不计。请你为老张编一程序来安排关灯的顺序,使从老张开始关灯时刻算起所有灯消耗电最少(灯关掉后便不再消耗电了).(n<=50)

    分析:注意到当前已经熄灭的路灯一定会是一段连续的区间(不可能路过一个路灯而不关这个灯吧),所以可以考虑区间(DP).

    (f[i][j][i/j])表示当前已经熄灭了路灯([i,j]),并且最后熄灭的是路灯(i/j),状态转移懒得写了,很容易想到.

    注意初始化(f[m][m][m]=0),其余正无穷,最后输出(f[1][n][1],f[1][n][n])的较小值即可.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=100;
    int bj[N],sum[N],dis[N][N],f[N][N][N];
    struct lamp{int pos,p;}a[N];
    int main(){
    	int n=read(),m=read();
    	for(int i=1;i<=n;++i){
    		a[i].pos=read();a[i].p=read();
    		sum[i]=sum[i-1]+a[i].p;
    	}
    	for(int i=1;i<n;++i)
    		for(int j=i+1;j<=n;++j)
    			dis[i][j]=dis[j][i]=a[j].pos-a[i].pos;		
    	memset(f,0x3f,sizeof(f));f[m][m][m]=0;
    	for(int len=2;len<=n;++len){
    		for(int i=1;i+len-1<=n;++i){
    			int j=i+len-1;
    			f[i][j][i]=min(f[i+1][j][i+1]+dis[i][i+1]*(sum[i]+sum[n]-sum[j]),f[i+1][j][j]+dis[i][j]*(sum[i]+sum[n]-sum[j]));
    			f[i][j][j]=min(f[i][j-1][i]+dis[i][j]*(sum[i-1]+sum[n]-sum[j-1]),f[i][j-1][j-1]+dis[j-1][j]*(sum[i-1]+sum[n]-sum[j-1]));
    		}
    	}
    	printf("%d
    ",min(f[1][n][1],f[1][n][n]));
        return 0;
    }
    
    
  • 相关阅读:
    366. Find Leaves of Binary Tree输出层数相同的叶子节点
    716. Max Stack实现一个最大stack
    515. Find Largest Value in Each Tree Row查找一行中的最大值
    364. Nested List Weight Sum II 大小反向的括号加权求和
    156. Binary Tree Upside Down反转二叉树
    698. Partition to K Equal Sum Subsets 数组分成和相同的k组
    244. Shortest Word Distance II 实现数组中的最短距离单词
    187. Repeated DNA Sequences重复的DNA子串序列
    java之hibernate之基于主键的双向一对一关联映射
    java之hibernate之基于主键的单向一对一关联映射
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11632499.html
Copyright © 2011-2022 走看看