• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Onway

            我是一只菜菜菜菜鳥...
            posts - 61, comments - 56, trackbacks - 0, articles - 34

            pku 1651 矩陣連乘

            Posted on 2010-08-26 21:38 Onway 閱讀(836) 評論(0)  編輯 收藏 引用 所屬分類: 傷不起的ACM
             

            pku 1651 Multiplication Puzzle

            題意:給出一組N個數,每次從中抽出一個數(第一和最后一個不能抽),該次的得分即為抽出的數與相鄰兩個數的乘積。直到只剩下首尾兩個數為止。問最小得分是多少。

            最優子結構:

            假設總得分最小時最后抽出的數在k位置,則在1:k和k:n之間的得分也是最小的。因為如果1:k或者k:n具有更小得分,則總得分會更小,與假設矛盾。

            狀態設計:

            設dp[i][j]為第i個數到第j個數的最小得分,則dp[1][n]即為題中的解。

            1<=i<=n-2;i+2<=j<=n;

             

            dp方程:

            dp[i][j]=min(dp[i][k]+dp[k][j]+s[i]*s[k]*s[j]);i<k<j;

            觀察方程,第一維中依賴的是i以后的值,第二維依賴的是j之前的值,所以第一維循環采用逆序循環,第二維采用順序循環。

             
            Memory: 756K Time: 0MS
            Language: G++ Result: Accepted

            #include <iostream>
            #include 
            <stdio.h>
            #include 
            <cstring>
            using namespace std;
            int dp[103][103],s[103];
            int main()
            {
                
            int n,i,j,k,min;
                scanf(
            "%d",&n);
                
            for(i=1;i<=n;++i)
                    scanf(
            "%d",&s[i]);     
                memset(dp,
            0,sizeof(dp));
                
            for(i=n-2;i>=1;--i)
                    
            for(j=i+2;j<=n;++j)
                    {
                        min
            =i+1;
                        
            for(k=i+2;k<=j-1;++k)
                            
            if((dp[i][k]+dp[k][j]+s[i]*s[j]*s[k])<(dp[i][min]+dp[min][j]+
                                s[i]
            *s[j]*s[min]))
                                    min
            =k;
                        dp[i][j]
            =dp[i][min]+dp[min][j]+s[i]*s[j]*s[min];   
                    }
                cout
            <<dp[1][n]<<endl;
                
            return 0;
            }


            這個題目折騰了我很久,估計也有五六個小時??赡苁翘茫ㄒ部彀雮€月了)沒做過題,也可能是對矩陣連乘這類DP,或者直接是對DP沒有更深入的理解(其實真正領悟DP又何嘗簡單?可以原諒)。其實矩陣連乘,在前幾天才看了第二遍,當時沒看書上的代碼,認為對于DP看方程看代碼其實是沒多少意思的,重要的是那個思路,問題的分析,子結構的證明,然后自己寫方程寫代碼。

            我是百度矩陣連乘搜到這個題目的,所以這個題目的方法一開始就知道。最先自己簡單的分析了一下子結構,然后找了個方程就開始寫遞歸,結果調試就卡住了。然后沒用遞歸,用數組,用堆棧又寫了兩次,發現都是卡在了同一個地方。

            后來懷疑起子結構和方程,原來對子結構沒有搞清楚,寫出的方程也錯的很不靠譜。待我通過了這個題后,看回自己的DP方程,發現兜了一大圈,還真是回到了矩陣連乘這里。

            對于一個方法已經知道,類型也見過的題目,總是有一點輕視,加之對原來了解的就不深入,犯錯就很容易理解了。

             

            最后說說編程上的知識:

            1, memset,strlen等字符串處理函數在G++要用到<cstring>頭文件

            2, scanf,printf要用到<stdio.h>頭文件

            3, ;abs在<cstdlib>中;fabs,sin,sqrt等數學函數在<cmath>中

            久久综合九色综合网站| 国産精品久久久久久久| 久久综合鬼色88久久精品综合自在自线噜噜| AA级片免费看视频久久| 久久精品成人免费观看97| 亚洲综合伊人久久大杳蕉| 97久久久精品综合88久久| 久久这里有精品视频| 久久久久亚洲AV成人片| 精品久久久久久无码中文野结衣 | 精品少妇人妻av无码久久| 国内精品久久久久影院网站| 一本色道久久88—综合亚洲精品 | 88久久精品无码一区二区毛片 | 国产69精品久久久久9999| 久久精品中文无码资源站| 国产69精品久久久久9999| 亚洲色婷婷综合久久| 亚洲日韩欧美一区久久久久我| 久久99久久99小草精品免视看 | 一级做a爰片久久毛片免费陪 | 国产精品久久久久久久人人看| 日本精品久久久久中文字幕8| 无码人妻久久一区二区三区 | 久久青草国产精品一区| 久久夜色精品国产网站| 国产成人精品久久| 精产国品久久一二三产区区别| 日韩电影久久久被窝网| 亚州日韩精品专区久久久| 久久精品成人| 久久人人爽人爽人人爽av| 国产精品VIDEOSSEX久久发布| 国产精品久久永久免费| 久久国产精品成人免费| 亚洲成色999久久网站| 国产综合成人久久大片91| 青青热久久国产久精品 | 香蕉久久一区二区不卡无毒影院 | 99久久国产综合精品五月天喷水| 久久er热视频在这里精品|