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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

环形石子合并

發布時間:2025/3/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 环形石子合并 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description 在一個圓形操場的四周擺放N堆石子(N≤100),現要將石子有次序地合并成一堆。規定每次只能選相鄰的兩堆合并成新的一堆,并將新的一堆的石子數,記為該次合并的得分。編一程序,讀入堆數N及每堆石子數(≤100)選擇一種合并石子的方案,分別得到合并這N堆石子為一堆,可以得到的最大得分和最小得分 Input 輸入包含多個例子。第一行為N,即石子堆的數目,以下一行為N個整形,分別代表每堆石子的數目。當N=0時,輸入結束。 Output 對每個例子,輸出其最小得分和最大得分,這兩個數值以空格間隔開,每個例子占一行。 Sample Input 6 30 35 15 5 10 20 3 1 2 3333 6 3 4 5 6 7 8 0 Sample Output 275 475 3339 6671 84 125 Hint


分析 : 動態規劃的典型題目。 從合并相鄰兩個堆開始,三個堆。。。。一直到N個堆。

? ?由于是環形,我延長了數組長度,用來將環形變換成線性。


以下代碼

/**/ #include <bits/stdc++.h> using namespace std ; #define N 100 int dp[N*2][N*2] ; // dp(i,j) 表示第i堆石子到第j堆石子的合并后的最優值 int getCount(int a[],int i, int j){int sum = 0 ;for (;i<=j;++i)sum+=a[i] ;return sum ; } int getMaxScore(int a[] , int Num){memset(dp,0,sizeof dp);int maxscore = 0 ;for (int l = 1; l < Num ;++l){//l 是合并后的長度for (int i = 0 ; i < Num*2-1 ; ++i){// i 是合并的起始位置if (i+l>=2*Num-1)continue;int count = getCount(a,i,i+l);for (int k = 0 ; k < l ; k++ ){ //k代表合并時 第一堆的數量dp[i][i+l] = max(dp[i][i+l] , dp[i][i+k]+dp[i+k+1][i+l]+count);// printf("i=%d , k = %d , j = %d, dp=%d\n",i,k,i+l,dp[i][i+l]);}}}for (int i =0 ; i < Num ;++i){maxscore = max(maxscore , dp[i][i+Num-1]) ;}return maxscore; } int getMinScore(int a[] , int Num){memset(dp,0,sizeof dp);int maxscore = 0x7fffffff ;// cout<<"max"<<maxscore<<endl;for (int l = 1; l < Num ;++l){//l+1 是合并后的長度for (int i = 0 ; i < Num*2-1 ; ++i){// i 是合并的起始位置if (i+l>=2*Num-1)continue;int count = getCount(a,i,i+l);// cout<<"count :"<<count <<endl;dp[i][i+l] = 0x7fffffff;for (int k = 0 ; k < l ; k++ ){ //k代表合并時 第一堆的數量dp[i][i+l] = min(dp[i][i+l] , dp[i][i+k]+dp[i+k+1][i+l]+count);// printf("i=%d , k = %d , j = %d, dp=%d\n",i,k,i+l,dp[i][i+l]);}}}for (int i =0 ; i < Num ;++i){maxscore = min(maxscore , dp[i][i+Num-1]) ;}return maxscore; } int main(){int Num ;int s[N];while (cin>>Num&& Num!=0){for (int i = 0 ; i < Num ; ++i){cin>> s[i];s[i+Num] = s[i] ;}cout<<"minscore "<<getMinScore(s,Num)<<endl;cout<<"maxscore "<<getMaxScore(s,Num)<<endl;}return 0; }

總結

以上是生活随笔為你收集整理的环形石子合并的全部內容,希望文章能夠幫你解決所遇到的問題。

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