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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】