uva 437(不用記憶化搜尋解)
阿新 • • 發佈:2019-01-05
思路:放程式碼上了
程式碼如下:
/* 最優解是max height 最優子結構是以i方塊作為最後一塊的最大長度 子問題的最優解是以前1,2,3...i-1個方塊作為最後一塊的最大長度 顯然:最優子結構包含了子問題的最優解 並且這些子問題的解之間相互獨立(其中一個問題的解,不會影響另外一個) 重疊子問題:每次都不用再計運算元問題的解,因為這些解都已經儲存在了表中 綜上:用dp[i]儲存以i方塊作為最後一塊的最大長度,dp[i]=dp[k](k=1...n && block[i]>block[k]); ans=max(dp[1...n]); 複雜度(O(n^2)) ; 這題的坑點。。。別的想法都沒錯,只有一個地方錯了,如果是無序的(後面的可能可以放到前面的頂上) 就說明子問題的最優解不是以前1,2,3...i-1個方塊作為最後一塊的最大長度而是1...n,但是因為是無序的所以 i..n作為最後一塊的長度是不可知的,所以會導致錯誤 如果先按照面積排序,那麼後面的方塊,就不能放到前面的頂上了 子問題的最優解是以前1,2,3...i-1個方塊作為最後一塊的最大長度 如果是用記憶化搜尋就不存在這個問題,因為每次呼叫的值,一定是確定的以i結尾的最大高度 */ #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int dp[200]; struct node { int x,y,z; }block[200]; bool cmp(node a,node b) { return a.x * a.y<b.x * b.y; } int n; int main() { int Case=1; while(scanf("%d",&n),n) { int num=1; while(n--) { int temp[3]; for(int i=0;i<3;i++) { scanf("%d",&temp[i]); } sort(temp,temp+3); do { block[num].x=temp[0]; block[num].y=temp[1]; block[num++].z=temp[2]; }while(next_permutation(temp,temp+3)); } sort(block+1,block+num+1,cmp); int maxx=0; for(int i=1;i<num;i++) { dp[i]=block[i].z; for(int j=1;j<num;j++) { if(block[i].x>block[j].x && block[i].y>block[j].y) { dp[i]=max(dp[j]+block[i].z,dp[i]); } } maxx=max(dp[i],maxx); } printf("Case %d: maximum height = %d\n",Case++,maxx); } return 0; }