標籤:class blog code http ext 資料
提示:這是屬於動態規劃問題。動態規划算法通常用於求解具有某種最優性質的問題。在這類問題中,可能會有許多可行解。每一個解都對應於一個值,我們希望找到具有最優值的解。
其實這道題目有一些問題:不能交換位置,這個關鍵的資訊在題目中間沒有進行說明。
編程思路是:需要三個數組,第一個數組存放原資料。第二個數組用於存放人數:從左向右遍曆時,對於當前的資料(身高),尋找合格人數,要求是從小到大排列的最大數。第三個數組用於存放人數:從右向左遍曆,對於當前的資料,尋找合格人數,要求從大到小排列的最大數。最後,通過第二個數組和第三個數組對應位置的資料之和,再減去1,來求得最佳解。
問題有待解決:我們只能得到最優解的人數,但是不能得到是那些人組成了合唱隊。不過我發現這是動態規劃問題普遍存在的現象。
來源程式如下:
#include <iostream>using namespace std;const int maxn = 100 + 1;int main(){int n;int a[maxn];int f1[maxn];//存放合唱隊的人數(從左向右)int f2[maxn];//存放合唱隊的人數(從右向左)cin>>n;for(int i=1;i<=n;i++)//第0個位置不存放資料,符合平常的思維習慣。cin>>a[i];for(int i=1;i<=n;i++)//由左向右依次遍曆 {f1[i] = 1;//至少有一個人符合條件,就是他自己。所以賦初值1.for(int j=1;j<i;j++){if(a[i]>a[j]&&f1[i]<f1[j]+1) //f1[i]<f1[j]+1很關鍵的條件,動態問題f1[i]= f1[j]+1;} }for(int i=n;i>=1;i--)//由右向左依次遍曆{f2[i] = 1;//至少有一個人符合條件,就是他自己。所以賦初值1.for (int j=i+1;j<=n;j++){if(a[i]>a[j]&&f2[i]<f2[j]+1) f2[i]=f2[j]+1;}}int ans = 0;for(int i=1;i<=n;i++)if(ans<f1[i]+f2[i]-1) ans=f1[i]+f2[i]-1;//最佳解cout<<n-ans<<endl;//需要出列的人數return 0;}運行結果:
總結:這是一道初級題目。最開始看到這個題目的時候,真是毫無頭緒,後來就想到找到最高的人,然後以這個人為中心,分別向前和向後遍曆,其實這種思想本身就已經偏離了動態規劃問題本身。找最高的人和他所在的位置,是不對的。動態規劃問題,是我值得弄明白的問題,希望通過一些簡單的例子可以理清頭緒。