***SPOJ - GCJ1C09C Bribe the Prisoners【贿赂囚犯】

原题链接

题目:
n 组测试数据,有p个人在监狱,要放出q个人,这些人的编号为a[1]~a[q],每放出一个人,他周围的人(两边连续的直到碰到空的监狱或者尽头)都要贿赂1枚金币,问最少花费多少金币。

思路:
dp[i][j]表示释放a[i]和a[j]之间的囚犯所需要的最少金币数。
初始化:dp[i][i+1]=0(因为a[i]和a[i+1]之间没有待释放囚犯),其他为INF。
动态方程:dp[i][j] = min(dp[i][j],dp[i][k]+dp[k][j]) + a[j] - a[i] - 2
(a[k]为a[i]和a[j]之间的一名待释放放囚犯)

AC代码:

#include <iostream>
#include <cstdio>  
#include <algorithm>
#include <cmath>  
using namespace std; 


int n, p, q, a[105], dp[105][105];
int INF = 429496725;

int main()
{
    int i, j, k, t;
    scanf("%d", &n);
    for(i = 1; i <= n; i++){
        for(j = 0; j <= q + 1; j++){
            fill(dp[j], dp[j] + 1 + q, INF);
    }
        scanf("%d %d", &p, &q);
        for(j = 1; j <= q; j++){
            scanf("%d", &a[ja]);
    }
    a[0] = 0;
    a[q + 1] = p + 1;
    for(j = 0; j <= q; j++){
        dp[j][j + 1] = 0;
    } 
    for(j = 2; j <= q + 1; j++){  //间隔j 
        for(k = 0; k + j <= q + 1; k++){  
          //释放a[k]到a[k + j]之间需释放的囚犯 
            int bribe = INF;
            for(t = k + 1; t < k + j; t++){
                bribe = min(bribe, dp[k][t] + dp[t][k + j]);
            }
            dp[k][k + j] = bribe + a[k + j] - a[k] - 2; 
            //两端不算(-1),被释放的囚犯不算(-1) 
        }
    }
        printf("Case #%d: %d\n", i, dp[0][q + 1]);
    } 
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值