【每日一题】P1220 关路灯 区间dp

经典区间dp

P1220 关路灯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

【每日一题】P1220 关路灯 区间dp_第1张图片

败犬二人组

大意:一个村庄有一条路,有一个人关灯,每个灯的功率不一,要怎么关灯才能使耗电最小

看到题目之后先分析,假如两侧只有两盏灯、三盏灯、四盏灯。。。。一直到n盏灯,属于递推关系(每多一盏灯多两次判断)递推式和数量相关,存在两种状态(位于已经关掉一定数量的灯的左边,或者右边

梳理一下状态,(左端点,右端点,所在位置(0在左,1在右)dp[i][j][0]/dp[i][j][1]

得到递推式:

dp[i][j][0]=min(dp[i+1][j][0]+(a[i+1]-a[i])*(s[n]+s[i]-s[j]),dp[i+1][j][1]+(a[j]-a[i])*(s[n]+s[i]-s[j]));
dp[i][j][1]=min(dp[i][j-1][1]+(a[j]-a[j-1])*(s[n]+s[i-1]-s[j-1]),dp[i][j-1][0]+(a[j]-a[i])*(s[n]+s[i-1]-s[j-1]));

前缀优化不多讲:

for(int i=1;i<=n;i++)cin>>a[i]>>b[i];
for(int i=1;i<=n;i++)s[i]=s[i-1]+b[i];

最后别忘了最大值初始化(求最小值)

给出ac代码:

#include
using namespace std;
int dp[105][105][3];
int a[105],s[105],b[105];
int main(){
	int n,c;
	cin>>n>>c;
	for(int i=1;i<=n;i++){
		cin>>a[i]>>b[i];
	}
	for(int i=1;i<=n;i++){
		s[i]=s[i-1]+b[i];
	}
	
	memset(dp,0x3f,sizeof(dp));
	dp[c][c][0]=0;
	dp[c][c][1]=1;
	for(int l=1;l

这几天回头看看区间dp和环形dp,未来几天的题目也会围绕这两种题型

你可能感兴趣的:(每日一题,动态规划,动态规划)