Comet OJ - Contest # 8 C title runic power dynamic programming dp

Topic link: https:? //Cometoj.com/contest/58/problem/C problem_id = 2760
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description
code This question is very simple, the main point is there is a pit. We may think of going to start planning how to get dynamic, such as which of the two first fusion, and fusion which of the two first, and then deal with * k interval; or the order reversed. Think so, the whole process of dynamic programming will become very complicated.

But if we let go of some of the visual field, or take the time to simulate what we will find, in all cases not * k runes, regardless of choice, and ultimately to merge into a rune, then the total energy released in fact, it is unchanged. We need to do, in fact, is to determine whether to have * k interval, the interval from where to start, where to end, in order to make the final energy as small as possible.

In this case, dp dimension is actually on the set, because the order does not affect integration, we directly adjacent to each initial array are integrated, O (n) again in the past, each has four states, understand the code directly, in comments he continued.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <string.h>
const int MAX=1e6+5;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
/// https://cometoj.com/contest/58/problem/C?problem_id=2760

ll a[MAX], b[MAX], dp[MAX][5];
int main()
{
  int i, j, n, k;
  cin >> n >> k;
  for (i=0; i<n; i++)
    scanf("%lld%lld", &a[i], &b[i]);
  for (i=1; i<n; i++)/// 状态数组dp从上向下滚动,对应符石从左到右
  {
    dp[i][0] = dp[i-1][0] + a[i]*b[i-1];/// 直接与左边符石融合的情况,顺带上左边
    ///符石和左边的左边符石直接融合产生的能量。dp[i][0]的记录只是为了dp[i][1]的
    ///选择做铺垫,真正的完全不*k的情况会在dp[i][2]被选择
    
    dp[i][1] = min(dp[i-1][0]+k*a[i]*b[i-1], dp[i-1][1]+k*k*a[i]*b[i-1]);/// 两种
    ///状态进行选择,一种是左符石没*k,i符石自己乘;一种是i-1符石和i符石一起乘,
    ///取最优情况记录下来,反正不论选哪个,dp[i][1]记录的都是*k区间覆盖到i符石
    ///的情况
    
    dp[i][2] = min(dp[i-1][1]+k*a[i]*b[i-1], dp[i-1][2]+a[i]*b[i-1]);/// 也是二选
    ///一,一种是i-1符石*k了,到i这里断了不乘了;一种是i-1没乘,i也不乘。所以
    ///dp[i][2]记录的是*k区间没覆盖到i符石的情况
  }
  cout << min(dp[n-1][1], dp[n-1][2]);/// 这里最终取最优
  return 0;
}

In fact, there is finally some interval k, not between the region k these two results, the optimal solution is recorded dp release of energy in each state, so max out a final result.

Published 19 original articles · won praise 0 · Views 501

Guess you like

Origin blog.csdn.net/qq_43317133/article/details/99674414