動態規劃法—-多邊形遊戲問題

來源:互聯網
上載者:User

一、題目

     給出一個多邊形,滿足:

          1. 每個頂點是一個數值

          2. 每條邊是一個符號

     我們將某個邊斷開,形成一條數值和符號組成的鏈,然後計算這條鏈的值。

          1· 可以選擇任意一條邊斷開。

          2.求鏈的值時,可以不必按運算子的優先順序順序,任意選擇先後

    題目的要求是得到最大的值

 

二、樣本

 

 

三、分析

      1. 如,我們將圖的資訊儲存如下:

          頂點數:REAL_SIZE = 3

          頂點:v[3] = {1,2,3}

          邊: op[3] = {'+','x','+'}

     

      2. 假如我們從 邊i 斷開,則形成了鏈

          v[i],op[i+1],v[i+1],op[i+2] .....v[i+s-1],op[s],v[i+s]...op[i-1],v[i-1]

 

          計算得到其最大值,題目要求的最大值,也就是分別將每個邊斷開後,能得到的每條鏈的最大值中的最大的。

 

      3. 為了計算方便,我們記:

          p[i,j] 表示從頂點i開始,包括j個頂點的鏈

          m[i,j,0]表示這條鏈的最小值

          m[i,j,1]表示這條鏈的最大值

          這樣 i 從 0到REAL_SIZE 的所有 m[i,REAL_SIZE,1]中最大的就是題目要的結果

 

      4. 將p[i,j]在op[i+s]處斷開,則形成兩條鏈p[i,s],和p[i+s,j-s]

          得到p[i,s]和p[i+s,j-s]的最小值和最大值,就可以得到p[i,j]在s處斷開的最大值最小值

          當s 從1開始到 j-1,分別得到 對應的斷開方法的最值,從這些最值中選擇最小和最大的作為m[i,j,0]和m[i,j,1]

 

四、代碼如下

          #include<stdio.h></p><p>//--------------------------預定義與全域變數------------------------------------<br />#define MAX_VETEX_SIZE 20 //程式能接受的最大頂點數目</p><p>int REAL_SIZE; //程式中實際的頂點數目<br />int m[MAX_VETEX_SIZE][MAX_VETEX_SIZE+1][2]; //儲存最大最小值(第二維表示鏈中頂點個數)<br />int v[MAX_VETEX_SIZE]; //頂點(數值)<br />char op[MAX_VETEX_SIZE]; //邊(符號)</p><p>//--------------------------初始化m數組-----------------------------------------<br />void init_m(){<br />int i;<br />for(i=0;i<REAL_SIZE;i++){<br />m[i][1][0] = v[i]; //鏈中只有一個頂點i<br />m[i][1][1] = v[i];<br />}<br />}</p><p>//-----------------------返回四個數中的最值---------------------------------------------<br />void getMin_Max(int n1,int n2,int n3,int n4,int* min,int* max){<br /> //返回四個運算元中的最大最小值<br />*min = (n1>n2)?((n2>n3)? (n3>n4? n4:n3):(n2>n4? n4:n2))<br /> :((n1>n3)? (n3>n4? n4:n3):(n1>n4? n4:n1));</p><p>*max = (n1<n2)?((n2<n3)? (n3<n4? n4:n3):(n2<n4? n4:n2))<br /> :((n1<n3)? (n3<n4? n4:n3):(n1<n4? n4:n1));<br />}</p><p>//-----------------------擷取有斷點的最大最小值--------------------------------------<br />void minMax(int i,int s,int j,int* minf,int* maxf){<br /> //p[i,j]從s處斷開的最大值maxf 與 最小值minf<br />//int e[4]; //ac,ad,bc,bd 的值<br />int a,b,c,d,r;<br />a = m[i][s][0]; //a 儲存從i 到 i+s頂點構成鏈的最小值<br />b = m[i][s][1];</p><p>r = (i+s)%REAL_SIZE;</p><p>c = m[r][j-s][0];<br />d = m[r][j-s][1];<br />//printf("i=%d; s=%d; j=%d; r=%d/n",i,s,j,r);<br />if(op[r] == '+'){ //處理加號<br />*minf = a+c;<br />*maxf = b+d;<br />}<br />else{ //處理乘法<br />getMin_Max(a*c,a*d,b*c,b*d,minf,maxf); //擷取ac,ad,bc,bd 的最大最小值<br />}<br />}</p><p>//------------------------------擷取結果-------------------------------------------------<br />int Poly_Max(){<br />int minf,maxf,temp;<br />int i,j,s;<br />for(j=2;j<=REAL_SIZE;j++){ //控制每個鏈中的頂點個數<br />for(i=0;i<REAL_SIZE;i++){ //控制每個鏈中的頂點的起始位置<br />for(s=1;s<j;s++){<br />minMax(i,s,j,&minf,&maxf);<br />if(m[i][j][0] > minf) m[i][j][0] = minf;<br />if(m[i][j][1] < maxf) m[i][j][1] = maxf;<br />}<br />//此時已經獲得了從i到i+j的頂點所有s對應的值中最大和最小<br />}<br />}</p><p> //求所有長度為REAL_SIZE個頂點的鏈中,值最大的<br />temp = 0;<br />for(i=1;i<REAL_SIZE;i++){<br />if(m[i][REAL_SIZE][1] > m[temp][REAL_SIZE][1]){<br />temp = i;<br />}<br />}</p><p>return m[temp][REAL_SIZE][1];<br />}</p><p>//---------------------------------主函數--------------------------------------------------<br />void main(){<br />int i =0;</p><p>scanf("%d",&REAL_SIZE); //使用者輸入頂點數目<br />for(i=REAL_SIZE-1;i>=0;i--){ //頂點和邊資訊<br />scanf("%d %c",&v[i],&op[i]); //輸入範例如下<br />} //3<br /> //1 x 3 + 2 +<br />init_m();</p><p> printf("%d/n",Poly_Max()); //輸出為 9<br />}

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.