題解 CF746D 【Green and Black Tea】

QianXuehao發表於2021-03-14

題目分析

這道題表面上看上去挺簡單,其實仔細研究一下還是值得鑽研的。我本人做這道題使用的任然是$ DFS01 $揹包。不過呢,與往常揹包不同的是,這次遞迴中需要加許多引數。就資料強度來看,棧問題不大。

遞迴過程

我們使用一個棧以及兩個臨時棧。每次在裡面$ push $當前的解。只有“G”與“B”。兩個棧分別處理和紅茶和和綠茶的情況。兩種情況都要考慮到已經連續喝了幾次某種茶。

在遞迴函式裡,我們用到$ dep,s,g,h,last $ 這幾個變數。分別代表深度、連續喝的總數、綠茶喝的總數、紅茶喝的總數以及上次喝的茶是啥。$ 0 $代表綠茶,\(1\)代表紅茶。

遞迴程式碼:

void dfs(int dep,int s,int g,int h,bool last)
{
    if(dep>n)
    {
        stack<string>temp1=temp;
        while(!temp1.empty())
        {
            cout<<temp1.top();
            temp1.pop();
        }
        exit(0);
    }
    else
    {
        if(last==0)
        {
            temp.push("G");
            if(g+1<=a)dfs(dep+1,s,g+1,h,!last);
            if(s+1<=b&&s<k) dfs(dep+1,s+1,g,h+1,last);
        else
        {
            cout<<"NO"<<endl;
            exit(0);
        }
    }
    else
    {
        temp.push("B");
        if(s+1<=b)dfs(dep+1,s,g,h+1,!last);
        if(g+1<=a&&s<k) dfs(dep+1,s+1,g,h,last);
        else
        {
            cout<<"NO"<<endl;
            exit(0);
        }
    }
    if(!temp.empty()) temp.pop();
}

主函式

最後主函式的程式就簡單了。像往常一樣,$ dep \(總是要是\) 1 \(開始,其他都是\) 0 $;但是有一個問題,我們不僅要考慮第一次喝綠茶的情況,第一次還可能是紅茶。所以我們在剛開始寫遞迴函式的時候,我們需要遞迴兩遍

主函式程式碼:

int main()
{
    cin>>n>>k>>a>>b;
    dfs(1,0,0,0,0);
    dfs(1,0,0,0,1);
    return 0;
}

完整程式碼

#include<bits/stdc++.h>
using namespace std;
int n,k,a,b;
stack<string>temp;
void dfs(int dep,int s,int g,int h,bool last)
{
    if(dep>n)
    {
        stack<string>temp1=temp;
        while(!temp1.empty())
        {
            cout<<temp1.top();
            temp1.pop();
        }
        exit(0);
    }
    else
    {
        if(last==0)
        {
            temp.push("G");
            if(g+1<=a)dfs(dep+1,s,g+1,h,!last);
            if(s+1<=b&&s<k) dfs(dep+1,s+1,g,h+1,last);
            else
            {
                cout<<"NO"<<endl;
                exit(0);    
            }
        }
        else
        {
            temp.push("B");
            if(s+1<=b)dfs(dep+1,s,g,h+1,!last);
            if(g+1<=a&&s<k) dfs(dep+1,s+1,g,h,last);
        else
        {
            cout<<"NO"<<endl;
            exit(0);
        }
    }
    if(!temp.empty()) temp.pop();
}
int main()
{
    cin>>n>>k>>a>>b;
    dfs(1,0,0,0,0);
    dfs(1,0,0,0,1);
    return 0;
}

相關文章