九度笔记之 1462:两船载物问题 - KingEasternSun的专栏 - 博客频道 - CSDN.NET
算法的时间复杂度与smallboat有关,所以如果两只船只重量相差很大的话,对小船求最大载重可以减少程序时间。
- 给定n个物品的重量和两艘载重量分别为c1和c2的船,问能否用这两艘船装下所有的物品。
- 输入:
- 输入包含多组测试数据,每组测试数据由若干行数据组成。
第一行为三个整数,n c1 c2,(1 <= n <= 100),(1<=c1,c2<=5000)。
接下去n行,每行一个整数,代表每个物品的重量(重量大小不大于100)。
- 输出:
- 对于每组测试数据,若只使用这两艘船可以装下所有的物品,输出YES。
否则输出NO。
- 样例输入:
3 5 8 6 3 3 3 5 8 5 3 4
- 样例输出:
NO YES
在一条船上尽可能多的放置货物,然后看剩下的货物另外一条船能否装下。
dp[j]表示容量为j的船只 所能装的最多的货物量,每次考虑一个货物,更新dp[j]
- for(int j = smallBoat; j>=boatw[i]; j--){
- dp[j] = std::max(dp[j],boatw[i]+dp[j-boatw[i]]);
- for(int j = smallBoat; j>=boatw[i]; j--){
- booldp[j] = booldp[j] || booldp[j-boatw[i]];
- }
- void init(int n){
- sumw = 0;
- for(int i = 1;i<n+1;i++){
- scanf("%d",boatw+i);
- sumw+=boatw[i];
- }
- }
- void judge(int n,int smallBoat,int bigBoat){
- if(sumw > smallBoat+bigBoat){
- printf("NO\n");
- return;
- }
- // *dp = new int[boat1 + 1];
- memset(dp,0,(smallBoat+1)*sizeof(int));
- for(int i = 1;i<n+1;i++){
- for(int j = smallBoat; j>=boatw[i]; j--){
- dp[j] = std::max(dp[j],boatw[i]+dp[j-boatw[i]]);
- }
- }
- if(sumw - dp[smallBoat] <=bigBoat ){
- printf("YES\n");
- }else
- printf("NO\n");
- }
也就是 在给定船只大小smallboat,和货物重量的情况下,哪些实际装载量可以实现。
booldp[j] 为真表示可以实现j个装载量,更新过程如下
- for(int j = smallBoat; j>=boatw[i]; j--){
- booldp[j] = booldp[j] || booldp[j-boatw[i]];
- }
算法的时间复杂度与smallboat有关,所以如果两只船只重量相差很大的话,对小船求最大载重可以减少程序时间。
- void judgenew(int n,int smallBoat,int bigBoat){//using bool
- if(sumw > smallBoat+bigBoat){
- printf("NO\n");
- return;
- }
- bool *booldp = new bool[smallBoat + 1];
- memset(booldp,0,(smallBoat+1)*sizeof(bool));
- booldp[0] = true;//Attention must be true
- for(int i = 1;i<n+1;i++){
- for(int j = smallBoat; j>=boatw[i]; j--){
- booldp[j] = booldp[j] || booldp[j-boatw[i]];
- }
- }
- for(int i = smallBoat;i>=0;i--){
- if(booldp[i]){
- if(sumw - i<=bigBoat)
- printf("YES\n");
- else
- printf("NO\n");
- return;
- }
- }
- }
while(~scanf("%d%d%d", &n, &c1, &c2)){ sum = 0; for(i = 1; i <= n; i++){ scanf("%d", &list[i]); sum += list[i]; } memset(dp, 0, sizeof(dp));//初始化dp = 0 for(i = 1; i <= n; i++) for(int j = c1; j >= list[i]; j--) dp[j] = dp[j] >= dp[j - list[i]] + list[i] ? dp[j] : dp[j - list[i]] + list[i]; //寻找在装在j,前i块重物中能容纳的最大,此处有点不容易理解 puts(dp[c1] + c2 >= sum ? "YES" : "NO"); }Read full article from 九度笔记之 1462:两船载物问题 - KingEasternSun的专栏 - 博客频道 - CSDN.NET