129_Bribe the Prisoners_DP


#include<cstdio>
#include<iostream>
#include<cstring>

using namespace std;

const int maxq = 100+10;
const int inf = 0x3f3f3f3f;

//待释放囚犯的位置 
int a[maxq];

//dp[i][j] 释放第 i 个和第 j 个之间所有囚犯所需金币
//这里的认为把需要释放的囚犯单独提取出来
//也就是说,i j 是 Q 里的序号 
int dp[maxq][maxq];

int main ()
{
	//P 牢房总数, Q 待释放的囚犯数 
	int P, Q;
	
	while(~scanf("%d %d", &P, &Q)){
		 
		for(int i= 1; i<= Q; i++)
			scanf("%d", a+i);
			
		//为了处理方便,将两端加入 Q 中 
		//此时dp[0][Q+1] 就是答案 
		a[0] = 0, a[Q+1] = P+1;
		
		//初始化
		//其实主要是为了初始化 dp[i][i+1]的值 
		memset(dp, 0, sizeof(dp));
		
		//从小到达枚举长度 
		for(int k= 2; k<= Q+1; k++){
		
			//枚举区间起点 
			for(int i= 0; i+k<= Q+1; i++){
				
				int temp = inf;
				
				//枚举区间内先释放的犯人 
				for(int j= i+1; j< i+k; j++){
					if(temp > dp[i][j] + dp[j][i+k])
						temp = dp[i][j] + dp[j][i+k];
				}
				
				//释放第一个犯人时要给两边无关的犯人发金币 
				dp[i][i+k] = temp + a[i+k] - a[i] - 2;
			}
		}
		
		printf("%d\n", dp[0][Q+1]);
	}
	
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值