zoukankan      html  css  js  c++  java
  • 洛谷 [P1220] 关路灯

    本题是一道区间DP,很容易设计出状态, dp[i][j]代表关掉i到j的路灯所耗的电量,但是对于新到一个路灯来说,可以是原来直接来的,也可以是掉头来的,于是还需要添加一维 0代表在区间的左端,1代表在区间的右端。从最开始所在的地方扩展。
    因为涉及连续区间,可以采用前缀和优化。

    有如下转移方程:
    dp[i][j][1]=min(dp[i][j-1][1]+pre[i][j-1](dis[j]-dis[j-1]),dp[i][j-1][0]+pre[i][j-1](dis[j]-dis[i]));
    dp[i][j][0]=min(dp[i+1][j][0]+pre[i+1][j](dis[i+1]-dis[i]),dp[i+1][j][1]+pre[i+1][j](dis[j]-dis[i]));

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    const int MAXN=105;
    int init(){
    	int rv=0,fh=1;
    	char c=getchar();
    	while(c<'0'||c>'9'){
    		if(c=='-') fh=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9'){
    		rv=(rv<<1)+(rv<<3)+c-'0';
    		c=getchar();
    	}
    	return fh*rv;
    }
    int dp[MAXN][MAXN][2],dis[MAXN],P[MAXN],n,loc,pre[MAXN][MAXN];
    int main(){
    	freopen("in.txt","r",stdin);
    	n=init();loc=init();
    	for(int i=1;i<=n;i++){
    		dis[i]=init();
    		P[i]=init();
    	}
    	for(int i=n;i>=1;i--){
    		dis[i]=dis[i]-dis[1];
    	}
    	pre[1][n]=0;
    	for(int i=1;i<=n-1;i++){
    		pre[i][n]=pre[i-1][n]+P[i-1];
    		for(int j=n-1;j>=i;j--){
    			pre[i][j]=pre[i][j+1]+P[j+1];
    		}
    	}
    	memset(dp,0x3f,sizeof(dp));
    	dp[loc][loc][0]=dp[loc][loc][1]=0;
    	for(int i=loc;i>=1;i--){
    		for(int j=i+1;j<=n;j++){
    			dp[i][j][1]=min(dp[i][j-1][1]+pre[i][j-1]*(dis[j]-dis[j-1]),dp[i][j-1][0]+pre[i][j-1]*(dis[j]-dis[i]));
    			dp[i][j][0]=min(dp[i+1][j][0]+pre[i+1][j]*(dis[i+1]-dis[i]),dp[i+1][j][1]+pre[i+1][j]*(dis[j]-dis[i]));
    		}
    	}
    	cout<<min(dp[1][n][0],dp[1][n][1]);
    	fclose(stdin);
    	return 0;
    }
    
    
  • 相关阅读:
    页面边距设置
    事件
    Ora-00906:missing left parenthesis
    Oracle
    数据转移:把数据从一个表转到另一个表
    修改字段默认值
    数据升级包
    触发器
    复制数据库数据
    VMware vSphere Client
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/7905872.html
Copyright © 2011-2022 走看看