日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【动态规划】叠放箱子问题(ssl 1640)

發(fā)布時(shí)間:2023/12/3 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【动态规划】叠放箱子问题(ssl 1640) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

疊放箱子問(wèn)題疊放箱子問(wèn)題問(wèn)

Description

某港口有一批集裝箱,將其編號(hào),分別為1至N。每一個(gè)箱子的外型尺寸都是一樣的,現(xiàn)在要將其中某些集裝箱疊放起來(lái),集裝箱疊放的規(guī)則如下:

1)每個(gè)集裝箱上最多只能直接疊放一個(gè)集裝箱。

2)編號(hào)較小的集裝箱不能放在編號(hào)較大的集裝箱之上。

3)每個(gè)集裝箱都給出了自身的重量和可承受的重量,每個(gè)集裝箱之上的所有集裝箱重量之和不得超過(guò)該集裝箱的可承受的重量。

現(xiàn)在要求你編程,從中選出最多個(gè)集裝箱,使之在滿足以上條件的情況下疊放起來(lái),即要求疊得盡可能地高。

Input

第一行是一個(gè)正整數(shù)N,表示共有N個(gè)集裝箱(1≤ N ≤1000)。

以下共有N行,每行兩個(gè)正整數(shù),中間用空格分隔,分別表示每個(gè)集裝箱的自身重量和可承受的重量,兩個(gè)數(shù)均為小于等于3000。

Output

輸出最多可疊放的集裝箱總數(shù)。運(yùn)行時(shí)間不超過(guò)去時(shí)10秒。

Sample Input

5

19 15

7 13

5 7

6 8

1 2

Sample Output

題目大意:

有n個(gè)箱子,每個(gè)箱子都有自己的編號(hào),自身重量,可承受重量(輸入第i+1行是編號(hào)為i的箱子自身重量和可承受重量),編號(hào)小的必須在編號(hào)大的下面,箱子上面只能直接放一個(gè)箱子,但上面的這個(gè)箱子上面還可以放箱子(例如下圖是合法的),求最多可疊放多少個(gè)箱子


方法一方法一

用一個(gè)二維數(shù)組f[i][j]來(lái)表示第i個(gè)箱子到第n個(gè)箱子重量為j時(shí)箱子的最大數(shù),然后從上往下從后往前一次推過(guò)來(lái),最后再?gòu)膄[1][i](i=0~6000)中選一個(gè)最大的即可

動(dòng)態(tài)轉(zhuǎn)移方程

f[i][j]=max{f[i+1][j]notselectif((j>=v[i])and(c[i]>=j?v[i]))f[i+1][j?v[i]]+1selectf[i][j]=max\left\{\begin{matrix} f[i+1][j]&&not select \\ if ((j>=v[i])and(c[i]>=j-v[i]))&f[i+1][j-v[i]]+1&select \end{matrix}\right.f[i][j]=max{f[i+1][j]if((j>=v[i])and(c[i]>=j?v[i]))?f[i+1][j?v[i]]+1?notselectselect?

說(shuō)明:

v為自身重量,c為可承受重量

#include<cstdio> #include<iostream> #include<cstring> using namespace std; int n,ans,v[1002],c[1002],f[1002][6002]; int main() {scanf("%d",&n);for (int i=1;i<=n;i++)scanf("%d%d",&v[i],&c[i]);memset(f,-127/3,sizeof(f));//初值f[n+1][0]=0;//初值for (int i=n;i>0;i--)for (int j=0;j<=6000;j++){f[i][j]=f[i+1][j];//不放if ((j>=v[i])&&(c[i]>=j-v[i]))//j>=v[i]是為了保證j-v[i]不為負(fù)數(shù),c[i]>=j-v[i]是為了保證他可以承受上面的重量f[i][j]=max(f[i][j],f[i+1][j-v[i]]+1);//狀態(tài)轉(zhuǎn)移方程}for (int i=0;i<=6000;i++)ans=max(ans,f[1][i]);//取最大值printf("%d",ans);return 0; }

方法二方法二

用f[i][j]來(lái)表示上面的i個(gè)箱子選j個(gè)箱子的最小值,然后每一層如果不放就直接等于上面的,如果放就要判斷是否能承受上方箱子的重量,再加上當(dāng)前重量去最小值

動(dòng)態(tài)轉(zhuǎn)移方程:

f[i][j]=min{f[i+1][j]notselectif(f[i+1][j?1]&lt;=c[i])f[i+1][j?1]+v[i]selectf[i][j]=min\left\{\begin{matrix} f[i+1][j]&amp;&amp;not select \\ if (f[i+1][j-1]&lt;=c[i])&amp;f[i+1][j-1]+v[i]&amp;select \end{matrix}\right.f[i][j]=min{f[i+1][j]if(f[i+1][j?1]<=c[i])?f[i+1][j?1]+v[i]?notselectselect?

#include<cstdio> #include<iostream> #include<cstring> using namespace std; int n,v[1005],c[1005],f[1005][1005],u; int main() {scanf("%d",&n);for (int i=1;i<=n;++i)scanf("%d%d",&v[i],&c[i]);for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)f[i][j]=2147483647/3;//初始化u=2147483647/3;f[n][1]=v[n];//初值for (int i=n-1;i>0;--i)//枚舉第i個(gè)箱子for (int j=1;j<=n-i+1;++j)//枚舉重量{f[i][j]=f[i+1][j];//不放就繼承上一個(gè)的最小重量if (f[i+1][j-1]<=c[i])//判斷是否能承受f[i][j]=min(f[i][j],f[i+1][j-1]+v[i]);//動(dòng)態(tài)轉(zhuǎn)移方程}for (int i=n;i>=0;--i)if (f[1][i]!=u)//若有變化及可輸出{printf("%d",i);break;//退出,避免重復(fù)輸出} }

總結(jié)

以上是生活随笔為你收集整理的【动态规划】叠放箱子问题(ssl 1640)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。