Chorus Formation~Dynamic Planning~2021.1.31

Catch the end of January, brush the wave questions~

Title description

N students stand in a row, and the music teacher asks (N-KN-K) students to stand out, so that the remaining KK students line up in a chorus formation.

The chorus formation refers to a formation: Suppose the K students are numbered 1,2,…,K1,2,…,K from left to right, and their heights are respectivelyInsert picture description here

Your task is to know the heights of all NN classmates, and calculate at least a few classmates to be out of the line, so that the remaining classmates can be formed into a chorus formation.
Insert picture description here

AC code

Note: The code and ideas are borrowed from Luogu blogger XSamsara.

#include <iostream>
using namespace std;
const int maxn = 105;
int a[maxn] = {
    
    0},f[2][maxn] = {
    
    0};
int main()
{
    
    
	int n,ans = 0;
	cin>>n;
	for(int i=1;i<=n;i++){
    
    
		cin>>a[i];
	}
	for(int i=1;i<=n;i++){
    
    
		for(int j=0;j<=i;j++){
    
    
			if(a[i] > a[j]){
    
    
				f[0][i] = max(f[0][i],f[0][j]+1);
			}
		}
	}
	for(int i=n;i>=1;i--){
    
    
		for(int j=n+1;j>=i;j--){
    
    
			if(a[i] > a[j]){
    
    
				f[1][i] = max(f[1][i],f[1][j]+1);
			}
		}
	} 
	for(int i=1;i<=n;i++){
    
    
		ans = max(ans,f[0][i] + f[1][i] - 1);
	}
	cout<<n-ans;
	return 0;
 } 

Explanation

① The idea of ​​dynamic programming is used. From the description of the title, we need to find the longest ascending sequence from the beginning and the longest ascending sequence from the end. After finding it, enumerate the middle height. For the tallest person, the state transition equation is:, ans = max(ans,f[0][i] + f[1][i] - 1)where f[0] stores the longest ascending order from the previous, and f[1] stores the longest ascending order from the back, -1because this longest ascending order includes the enumerated position, so f[0][i] + f[1][i]this position The value of is added twice, so it needs to be subtracted once. In this way, the longest ascending order is obtained, and the number of people who stay at most is obtained, and then the total number of people is subtracted, which is the number of people who walked the least.
②Find the longest in ascending order, taking from front to back as an example.

for(int i=1;i<=n;i++){
    
    //从第一个位置开始
	for(int j=0;j<=i;j++){
    
    //从第一个位置之前开始,由于输入的限定,第一个位置的值
	//一定是0。
		if(a[i] > a[j]){
    
    //注意dp的思想。
			f[0][i] = max(f[0][i],f[0][j]+1);
			//如果满足条件,则保留自己现在的值(前面可以留下的人数,包括自己)和
			//枚举值+1(即带上枚举的位置)的较大值。
		}
	}
}

Guess you like

Origin blog.csdn.net/fatfairyyy/article/details/113484395