P1220 关路灯

区间DP

题目

题解

$$ i :   f[i][j][1] = min (f[i + 1][j][0] + (wt + w[i]) * lt, f[i + 1][j][1] + (wt + w[i]) * (p[i + 1] - p[i])) $$

$$ j :    f[i][j][0] = min (f[i][j - 1][0] + (wt + w[j]) * (p[j] - p[j - 1]), f[i][j - 1][1] + (wt + w[j]) * lt);  $$

Code

//

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <stdlib.h>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <string>
#include <stdio.h>
#include <climits>
#include <stack>
#include <vector>
// #include <bits/stdc++.h>   //万能头

#define INF 0x3f3f3f3f
#define INT_INF 0x3f3f3f3f
#define LONGLONG_INF 0x3f3f3f3f3f3f3f3f
#define DOUBLE_INF 1E5 + 3;
#define ios\
    ios::sync_with_stdio(false); \
    cin.tie(nullptr); \
    cout.tie(nullptr)
#define TE true
#define FA false
#define fi first
#define se second
#define be begin
#define en end
#define FOR(k, lll, rrr) for (long long i = (lll); i <= (rrr); i ++ )
#define mef(x) memset (x, -1, sizeof (x))
#define mel(x) memset (x, 0, sizeof (x))
#define NIL -1
#define gdboff fclose(stdin), fclose(stdout)

#define gdb freopen("In.in","r",stdin), freopen("Out.out","w",stdout)
#define N 50 + 5
#define M 200000 + 5

using namespace std;

inline int read ()
{
    int x = 0;
	int f = 1;
	char c = getchar ();
	while (c < '0' || c > '9')
	{
		if (c == '-')
			f = -1;
		c = getchar ();
	}
	while (c >= '0' && c <= '9')
		x = (x << 1) + (x << 3) + (c ^ 48), c = getchar ();
	return x * f;
}

inline void write (int x)
{
	if (x < 0)
		putchar ('-'), x = -x;
	if (x > 9)
		write (x / 10);
	putchar (x % 10 | 48);
	return ;
}

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;

const int A_LEN = 1e6 + 10;
const int MOD = 1e9 + 7;

int n, c;
int w[N], f[N][N][3], p[N];

signed main ()
{
	n = read ();
	c = read ();

	for (int i = 1; i <= n; i ++ )
	{
		p[i] = read ();
		w[i] = read ();
	}

	for (int i = 1; i <= n; i ++ )
	{
		for (int k = 0; k <= 2; k ++ )
		{
			f[i][i][k] = INF;  // 初始化
		}
	}

	f[c][c][0] = f[c][c][1] = 0; // 老头所在的位置
	for (int s = 1; s <= n - 1; s ++ )
	{
		for (int i = 1; i + s <= n; i ++ )
		{
			int j = i + s;
			int lt = p[j] - p[i];  // 区间位置长度
			ll wt = 0;
			for (int wi = 1; wi <= n; wi ++ )
			{
				if (wi >= i && wi <= j)
					continue;
				wt += w[wi];
			} // 计算除区间内的功率
			f[i][j][1] = min (f[i + 1][j][0] + (wt + w[i]) * lt, f[i + 1][j][1] + (wt + w[i]) * (p[i + 1] - p[i]));
			f[i][j][0] = min (f[i][j - 1][0] + (wt + w[j]) * (p[j] - p[j - 1]), f[i][j - 1][1] + (wt + w[j]) * lt);
		}
	}
	cout << min (f[1][n][1], f[1][n][0]) << endl;
	return 0;
}

//g++ t.cpp -o t -std=c++11 -g
//gdb t

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值