P1220 关路灯

链接

https://www.luogu.com.cn/problem/P1220

思路

之前想错了:直接用dp[i][j]表示消除ij内的代价。但是还得再加一维度:即dp[i][j][0]表示消除之后处在左端;dp[i][j][1]表示消除后处在右端。
很显然,消除完了之后只可能处于两端,不可能路过不关灯。
所以对dp[i][j][0]就有递推式:

dp[i][j][0] = min(dp[i+1][j][0]+consume,dp[i+1][j][1]+consume)
dp[i][j][1] = min(dp[i][j-1][0]+consume,dp[i][j-1][1]+consume)
(后一条原理同上图,没画出来)
然后还有就是这个consume要注意是没有熄灭的灯耗费的能量,所以排除掉诸如[i+1.j]的电灯后算出来的值。
还有就是遍历问题:如果i外j内双向,那么dp[i][j][0]会无法更新,所以采用j外i内,看代码。
参考dew题解:https://www.luogu.com.cn/problem/solution/P1220

代码

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long

const int INF = LLONG_MAX;
const int N = 100;
int n, c;
int site[N], val[N];
int dp[N][N][2];

signed main()
{
	IOS;
	cin >> n >> c;
	for (int i = 1; i <= n; i++)cin >> site[i] >> val[i];
	for (int i = 1; i <= n; i++)val[i] += val[i - 1];
	memset(dp, 0x3f, sizeof(dp));
	dp[c][c][0] = dp[c][c][1] = 0;
	for(int j = c; j <= n; j++)
		for (int i=j-1;i>0;i--)
		{
			dp[i][j][0] = min(dp[i + 1][j][0] + (site[i + 1] - site[i]) * (val[n] - val[j] + val[i]),
				dp[i + 1][j][1] + (site[j] - site[i]) * (val[n] - val[j] + val[i]));
			dp[i][j][1] = min(dp[i][j - 1][0] + (site[j] - site[i]) * (val[n] - val[j - 1] + val[i - 1]),
				dp[i][j - 1][1] + (site[j] - site[j - 1]) * (val[n] - val[j - 1] + val[i - 1]));
		}
	cout << min(dp[1][n][0], dp[1][n][1]);
	return 0;
}
posted @   WHUStar  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示