Summer vacation topic tes02

Posted by spamoom on Mon, 29 Jul 2019 13:36:45 +0200

Topic A links; https://hihocoder.com/problemset/problem/1326

Significance: Enter a number of N; represent N strings (each string only exists 0 and 1), you have two operations, 0 to 1, 1 to 0; to make all 0 only exist in front of 1; find the least number of operations;

PS: All zeros can only be in front of 1; all final states satisfying the answer can be enumerated. The positions of all the demarcation points i are in front of 0 and i are all in front of 1. There are only len possibilities in total. Where your demarcation points are from, only len position demarcation (len is string length) can be established before an array record is made. Affix, that is, how many 0 before, how many 1 before; the last choice of the least is the answer;

#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1005;
char s[N];
int dp[N][2];
int main()
{
    int n;
    cin>>n;
    while(n--){
        cin>>s;
        int len=strlen(s);
        for(int i=0;i<len;i++)     
            dp[i][0]=0,dp[i][1]=0;

        if(s[0]=='0')             //Initialization 
            dp[0][0]=1,dp[0][1]=0;
        else    dp[0][1]=1,dp[0][0]=0;

        for(int i=1;i<len;i++){     //How many zeros and ones are there before finding the first position? 
            if(s[i]=='0'){
                dp[i][0]=dp[i-1][0]+1;
                dp[i][1]=dp[i-1][1];
            }
            else{
                dp[i][1]=dp[i-1][1]+1;
                dp[i][0]=dp[i-1][0];
            }
        }

        int ans=999999;
        for(int i=0;i<len;i++){   //Take the position i as the demarcation line and find the number of times that need to be changed (the number of times that all the 1 before i become 0 and all the 0 after i become 1) 
            if(s[i]=='1')
            ans=min(ans,dp[i-1][1]+dp[len-1][0]-dp[i][0]);
            else
            ans=min(ans,dp[i][1]+dp[len-1][0]-dp[i][0]);
        }
        cout << ans << endl;
    }

    return 0;
}

Of course, this approach is too cumbersome and a little silly; the correct solution is DP;

That is to say, if the first position is 0, then all of the preceding positions are 0. If it is 1, then all of the preceding positions are either 1 or all of the preceding positions are 0.

The DP equation is shown in the code.

#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1005;
char s[N];
int dp[N][2];//0 represents the current time of 0, and 1 represents the current time of 1. 
int main()
{
    int n;
    cin>>n;
    while(n--){
        cin>>s;
        int len=strlen(s);
        memset(dp,0,sizeof(dp)); //Initialization 
		if(s[0]=='0')
			dp[0][1]=1,dp[0][0]=0;
		else
		dp[0][0]=1,dp[0][1]=0;
		
		for(int i=1;i<len;i++){  
			if(s[i]=='0'){           //If it's currently zero, dp[i][0] is the number of my first zero. 
				dp[i][0]=dp[i-1][0];
				dp[i][1]=dp[i-1][1]+1;//dp[i][1] is the current minimum of 1 satisfying the condition, plus the operation of converting position 0 to position 1 
			}
			else{
				dp[i][1]=min(dp[i-1][0],dp[i-1][1]); //Maintain a minimum 
				dp[i][0]=dp[i-1][0]+1;//If this bit is changed to 0, then all of the preceding must be 0, plus this operation; 
			}
		}
        cout <<min(dp[len-1][0],dp[len-1][1])<< endl;
    }

    return 0;
}

Therefore, DP is to recurse all the i positions, whether 0 or 1 satisfies the condition.

Question C: http://codeforces.com/problemset/problem/1196/D1

Title: Give you the length of a string s, input the string, and ask you to find a length of K s substring is a RGB loop string substring, ask for the minimum number of changes to S;

ps: This problem is ingenious in building an array'R''G''B', you can, and then, all in this array cycle can create an array sum for the prefix; sum[0],sum[1] ____________.

sum[2] represents the prefix of three cycle modes from rgb cycle gbr cycle and brg cycle; sum+1 when sum is not equal to s; find out all the times of S string to be changed; and finally take the minimum value.

    #include <iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N = 2e5+10;
    int sum[3][N];
    char c[3]={'R','G','B'};
    int main()
    {
        int _;
        cin>>_;
        while(_--){
            int n,k;
            char s[N];
            cin>>n>>k;
            scanf("%s",s+1);
            for(int i=0;i<=n;i++){
                sum[0][i]=0;sum[2][i]=0;sum[1][i]=0;
            }
     
            for(int i=1;i<=n;i++){
                for(int j=0;j<3;j++){
                    if(s[i]!=c[(i+j-1)%3])    //Represents the number of cycles that need to be changed from j to i. 
                        sum[j][i]=sum[j][i-1]+1;
                    else
                        sum[j][i]=sum[j][i-1];
                }
            }
            int ans=N;
     
            for(int i=0;i<=n-k;i++)
                ans=min(min(sum[0][i+k]-sum[0][i],sum[1][i+k]-sum[1][i]),min(ans,sum[2][i+k]-sum[2][i]));
            cout << ans << endl;
        }
     
        return 0;
    }

Topic E: A tree-shaped DP, unfamiliar with the capsule, and later familiar with K; last link: http://codeforces.com/problemset/problem/1153/D

 

Question F: http://codeforces.com/problemset/problem/455/A

Title: A bored person plays a bored game, input n, that is, the number of N, if you want to score ai, then ai-1 and ai+1 scores will not be obtained;

ps: This question is for DP; that is, dp[i] denotes the values of ai and no ai scores. If dp[i] is a[i], then I-1 cannot be taken. The equation is dp[i-2]+a[i], otherwise dp[i]=dp[i-1].

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long int ll;
    const int N = 1e5+10;
    ll b[N];
    ll dp[N];
    int main()
    {
    	std::ios::sync_with_stdio(false);
    	cin.tie(0);
    	int minn=N,maxx=-N;
    	//cout<<N<<endl;
    	int n,temp;
    	cin>>n;
    	
    	for(int i=1;i<=n;i++){//Record the minimum and score 
    		cin>>temp;
    		b[temp]+=temp;
    		minn=min(minn,temp);
    		maxx=max(maxx,temp);
    	}
    	
    	
    	for(int i=minn;i<=maxx;i++){  //Recursion from Minimum to Maximum 
    		dp[i]=max(dp[i-1],dp[i-2]+b[i]);
    	}
    	
    	cout<<dp[maxx]<<endl;
    	
    }

 

Topics: iOS