洛谷 P1564 膜拜 题解

一个需要一点思维的 d p dp dp,对于这道题:

  1. 可以把序列中的所有 2 2 2改为 − 1 -1 1,就可以用前缀和统计相差的个数了。
  2. 线性 d p dp dp d p [ i ] dp[i] dp[i]表示到第 i i i个人需要的机房数。
  3. 状态转移:用前缀和对题意模拟,然后易得:
    d p [ i ] = m i n ( d p [ i ] , d p [ j − 1 ] + 1 ) 当 j < = i 时 dp[i]=min(dp[i],dp[j - 1] + 1) \quad当 j <= i时 dp[i]=min(dp[i],dp[j1]+1)j<=i
    4.上代码:
#include 
using namespace std;
const int maxn = 2e3 + 5e2 + 50;
int a[maxn], dp[maxn], sum[maxn], n, m;
int main () {
	cin >> n >> m;
	for(int i = 1; i <= n; i++) {
		cin >> a[i];
		if(a[i] == 2) sum[i] = sum[i - 1] - 1;
		else sum[i] = sum[i - 1] + 1;
	}
	memset(dp, 0x3f, sizeof(dp));
	dp[0] = 0;
	dp[1] = 1;
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= i; j++) {
			if(abs(sum[i] - sum[j - 1]) <= m || abs(sum[i] - sum[j - 1]) == i - j + 1) {
				dp[i] = min(dp[i], dp[j - 1] + 1);
			}
		}
	}
	
	cout << dp[n] << '\n';
	return 0;
}

你可能感兴趣的:(动态规划专题讲解,洛谷题解)