题目链接

https://www.dotcpp.com/oj/problem1551.html

题目大意

一圈,n个位置,m棵树,树不能挨着,必须把m棵树全部种下。每个位置都有一个美观度,种下树就可以获得对应位置的美观度,问最大美观度。

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N=35;
int ans,n,m;
int a[N];//美观度
int f[N];//用于标记i位置的花坛是否种树了
void dfs(int step,int sum,int num){//花坛序号 总美观度 已种树数
        //结束判断
    if(num>m) return ;//已种树数超过m棵
    if(step==n+1){//一圈转完,要是满足以下条件刷新答案,不满足就直接return了。
        if((!f[n]||!f[1])&&num==m){
            ans=max(ans,sum);
        }
        return ;
    }

        //开始判断
    if(step==1){//处于第一个位置时,可以选在在此种树,或者不种
        dfs(step+1,sum,num);//no
        f[step]=1;
        dfs(step+1,sum+a[step],num+1);//yes
        f[step]=0;
        return ;
    }
    if(!f[step-1]){//前一个位置没种树,那么本位置可以种树,也可以不种树
        f[step]=1;
        dfs(step+1,sum+a[step],num+1);//yes
        f[step]=0;
    }
    dfs(step+1,sum,num);//no
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    if(m>n/2){cout<<"Error!"<<endl;return 0;}//特判,没法种下全部m棵树

    dfs(1,0,0);
    cout<<ans<<endl;
}

总结

开始想着用dp做,没做出来。
dfs的三个return条件让我感到诧异,牛!
还可以用优先队列做,有时间会附上链接的!