機試演算法講解 第53題 動態規劃之如何擺放橘子

2021-07-04 06:28:35 字數 1716 閱讀 7428

/*

問題:有一堆柑橘,重量為0到2000,總重量不大於2000。從中取出兩堆放在扁擔兩頭,且兩頭重量相等,問符合條件的的每堆重量最大是多少。沒有符合條件的分堆方式則輸出

-1輸入:第一行時t,表示t個測試用例,對每個測試用例,包含乙個數字n,表名橘子數。第二行有n個數字,表明每個橘子的重量,1<=n<=100.如果是因為存在重量為0的橘子,

導致扁擔兩邊重量為0,那麼應該輸出0,否則輸出-1

思路:橘子放在第一堆或者第二堆造成兩堆之間的重量動態變化,設dp[i][j]:表示第i個橘子放入後,第一堆比第二堆重j時,兩堆的最大重量和

初始狀態:dp[0][0],dp[0][j](j!=0)為負無窮,表明其他狀態不存在

目標狀態:dp[n][0]/2即為所求。因為dp[n][0]表示的是總重量

橘子的3種擺放方式:放入第一堆,放入第二堆,不放入。設橘子重量為wei[i]

放入第一堆:dp[i][j]=dp[i-1][j+wei[i]]+wei[i]

放入第二堆:dp[i][j]=dp[i-1][j-wei[i]]+wei[i]

不放: dp[i][j]=dp[i-1][j]

複雜度:總重量<=2000,時間複雜度=狀態數量*狀態轉移複雜度=柑橘總數(n*2*2000)*o(1)=o(4000*m),n表示橘子的數量,

輸入:1

51 2 3 4 5

輸出:7

關鍵:1 注意重量可能為負,需要加偏置值2000

2 注意最後列印與判斷是dp[n][0+offset]/2.對於每個橘子,存在-2000到2000的共4000狀態量的變化,所以轉移值需要放在狀態量變化那層迴圈中

*/#include #include #include //設定偏置值

#define offset 200

//設定橘子最大數量+1

#define n 101

//設定最大正整數

#define int_max 0x7fffffff

int main(int argc,char* argv)

}} //初始化無效的狀態量

for(j = -200; j <= 200 ; j++)

//設定唯一的正確狀態量,dp[0][2000]=0

dp[0][0+offset] = 0;

n = icnt;//更新重量不為0的橘子的數量

//易錯,開始進行狀態轉移,遍歷每個柑橘,對每個柑橘,遍歷每種狀態量

for(i = 1 ; i <= n ; i++)

//如果放在第二堆

if(j-wei[i] >= -200 && -int_max!=dp[i-1][ j-wei[i]+offset ])

//取總重量重的較大值

if(itemp1 < itemp2)

//與不放橘子的總重量進行比較

if(itemp1 < dp[i-1][j+offset])

//更新當前狀態量為上述3個狀態量中的最大的乙個

dp[i][j+offset] = itemp1;

}//for

}//for

//如果總重量為0,注意加上偏置值

//if(dp[n][0]==0)

if(dp[n][0+offset]==0)

else

}system("pause");

getchar();

return 0;

}

機試演算法講解 第55題 Piggy Bank

問題 與乙個儲蓄罐,告知空的質量和當前重量,並給定一些錢幣的價值和相應的重量,求儲蓄罐中最少有多少現金。輸入 包含t組測試用例。第一行。每乙個測試用例包含2個整數e和f,表明空儲蓄罐的重量和裝滿錢的重量。10,000g,第二行是每個測試用例,包含乙個整數n 1 n 500 給出了各種硬幣的數量。接下...

機試演算法講解 第58題 輸入外掛程式

輸入外掛程式 scanf快於 cin,在scanf基礎上再次優化,使那些剛超時一點的程式能夠卡金時限範圍。原理 在讀入緩衝中字元的前提下,手動分析字串中輸入的整數 浮點數等我們需要的輸入型別,並將其儲存在變數中 include include include 輸入整數,並將整數儲存在引用變數ret中...

機試演算法講解 第7題 輸出梯形

問題 輸入高度h,輸出高為h,上底邊圍h的梯形 思路 由於多出的底邊x可以設為任意值,不放設x h 第1行,h h 第2行,列印h 1個空格,1個 然後列印h個空格,再列印1個 h 2 1 3 h 2 1 h 2 1 1個 h 2 2 4 h 3個空格,1個 h 2 2 1個 h 1 2 1個 h ...