贿赂囚徒 BRIBE THE PRISONERS
题目简述:监狱里要放囚徒,但是没那么简单,必须要有封口费给别的囚徒,否则她们就会大闹天宫,当遇到空牢房(因为有囚徒放出来了)或者碰壁了才会停止发放金币,问:怎样使给出的金币最少?
思路:可以用dp的做法

以下是代码(其实有个疑问,似乎不用函数做这题是做不出的?!)
#include <set> #include <map> #include <deque> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <bitset> #include <cstdio> #include <string> #include <vector> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> typedef long long ll; using namespace std; const int maxn =110; const int mod = 0; const int inf = 0x3f3f3f3f; ll t; int n, k; int a[maxn]; int dp[maxn][maxn]; int num = 0; void solve() { a[0] = 0; a[k + 1] = n + 1;//解决边界问题 cout << "Case #" << ++num << ": "; for (int i = 0; i <= k; ++i)dp[i][i + 1] = 0;//初始化 for (int i = 2; i <= k + 1; ++i) { //每次选择的范围都是i,从j到m的范围最小数等于从j到o加从第o到m的最小值 for (int j = 0; j + i <= k + 1; ++j) { //计算dp[i][j] int m = j + i, tot = inf;//tot用来保存当前区间的当前最好情况的花费金币数 for (int o = j + 1; o < m; o++)tot = min(tot, dp[j][o] + dp[o][m]);//求最初释放囚犯的最小金币数量; dp[j][m] = tot + a[m] - a[j] - 2;//此处就是当前区间最小值 } } cout << dp[0][k + 1] << endl; } int main() { cin >> t; while (t--) { //memset(dp, 0, sizeof dp); //dp为释放ij所需的金币 cin >> n >> k; for (int i = 1; i <= k; ++i)cin >> a[i]; solve(); } return 0; } //MOSHANG
补题不香吗

浙公网安备 33010602011771号