日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

蓝桥杯-算法提高-种树

發布時間:2025/3/15 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 蓝桥杯-算法提高-种树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2018-3-22

因為沒有會員,所以并不知道寫的對不對…

問題描述
  A城市有一個巨大的圓形廣場,為了綠化環境和凈化空氣,市政府決定沿圓形廣場外圈種一圈樹。園林部門 得到指令后,初步規劃出n個種樹的位置,順時針編號1到n。并且每個位置都有一個美觀度Ai,如果在這里種樹就可以得到這Ai的美觀度。但由于A城市土壤 肥力欠佳,兩棵樹決不能種在相鄰的位置(i號位置和i+1號位置叫相鄰位置。值得注意的是1號和n號也算相鄰位置!)。
  最終市政府給園林部門提供了m棵樹苗并要求全部種上,請你幫忙設計種樹方案使得美觀度總和最大。如果無法將m棵樹苗全部種上,給出無解信息。
輸入格式
  輸入的第一行包含兩個正整數n、m。
  第二行n個整數Ai。
輸出格式
  輸出一個整數,表示最佳植樹方案可以得到的美觀度。如果無解輸出“Error!”,不包含引號。
樣例輸入
7 3
1 2 3 4 5 6 7
樣例輸出
15
樣例輸入
7 4
1 2 3 4 5 6 7
樣例輸出
Error!

法一:遞歸

這個題目本身可能要求我們使用遞歸求解,因為給我們的數據并不是很大,step表示當前來到了第幾個花壇,sum表示當前的美觀度,num表示當前種的樹的數目。用f數組標記當前step位置是否種樹,目的是為了使相鄰兩個不同時種樹且頭和尾不同時種樹。

#include<iostream> #include<cstring> using namespace std;const int N = 30; bool f[N+1]; int a[N+1]; int m,n,res;void dfs(int step,int sum,int num){if (num>m) return ;if (step==n){if ((!f[0]||!f[n-1])&&num==m){res=max(res,sum); }return ;}if (step==0){dfs(step+1,sum,num);f[step]=true;dfs(step+1,sum+a[step],num+1);f[step]=false;return ;}if (!f[step-1]){f[step]=true;dfs(step+1,sum+a[step],num+1);f[step]=false;}dfs(step+1,sum,num); }int main(){while (cin>>n>>m){for (int i=0;i<n;i++){cin>>a[i]; }if (m>n/2) {cout<<"Error!"<<endl;continue;}res=0;dfs(0,0,0);cout<<res<<endl;} return 0; }

如果說m大于n/2的話,無法保證相鄰兩個不同時種樹,輸出Error!

法二:動態規劃
(1)如果說沒有 ” 每相鄰兩個不能同時種 ” 和 ” 環形 “這兩個條件的話,那么就等同于01背包問題,也就是說在n個物品中選擇m個所能獲得的最大的價值。
(2)如果說加了 ” 每相鄰兩個不能同時種 ” 這個條件的話,也就是說我們要是選擇某個商品的話,我們就得讓它前一個不選即可。
(3)如果說再加上 “環形” 這個條件的話,那么我們的第0個和第n-1個不能同時選,在遞歸方法中我們是使用f數組來標記的,這里我們就等同于在0~n-2和1~n-1中選擇最大值即可。
用dp[i][j]表示前i個坑,當前已經種了j棵樹所能獲得的最大的美觀度,那么如果說第i個坑我們選擇種的話,那么等同于前i-2個坑種j-1棵樹所能獲得的最大美觀度,如果說我們不種的話,那么就等同于前i-1個坑種j-1棵樹所能獲得的最大美觀度,我們需要求解0~n-2和1~n-1然后選擇最大值。

#include<iostream> #include<cstring> using namespace std;const int N = 30; int dp[N+1][N+1],v[N+1]; int m,n;int main(){while (cin>>n>>m){for (int i=0;i<n;i++){cin>>v[i];}if (m>n/2) {cout<<"Error!"<<endl;continue;}memset(dp,0,sizeof(dp));int r1,r2;dp[0][1]=v[0];dp[1][1]=max(v[0],v[1]);for (int i=2;i<n-1;i++){for (int j=1;j<=m;j++){dp[i][j]=max(dp[i-2][j-1]+v[i],dp[i-1][j]);}}r1=dp[n-2][m];memset(dp,0,sizeof(dp));dp[1][1]=v[1];dp[2][1]=max(v[1],v[2]);for (int i=3;i<n;i++){for (int j=1;j<=m;j++){dp[i][j]=max(dp[i-2][j-1]+v[i],dp[i-1][j]);}}r2=dp[n-1][m];cout<<max(r1,r2)<<endl;}return 0; }

總結

以上是生活随笔為你收集整理的蓝桥杯-算法提高-种树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。