Algorithm 使用最轻的托架在特定日期移动n个对象

Algorithm 使用最轻的托架在特定日期移动n个对象,algorithm,Algorithm,我必须解决这个问题,但我想不出任何算法。感谢您的帮助:) 问题:我们想用马车将n个具有不同重量的对象移动到另一个位置,但这样做的时间有限。我们一天只能使用一次运输工具,因为运输成本很高,我们希望选择一种运输工具,这种运输工具可以在给定的日期内运输我们所有的产品,但支付的费用最低,因此我们的目标是选择一种能完成这项工作的运输工具,其容量最小(随着运力的增加,我们必须支付的运费会大幅增加)。此外,物品应根据其重量进行移动,最小的物品优先 给定数据:n项,i个对象为Wi,d天 通缉令:c,显示所选车厢

我必须解决这个问题,但我想不出任何算法。感谢您的帮助:)

问题:我们想用马车将n个具有不同重量的对象移动到另一个位置,但这样做的时间有限。我们一天只能使用一次运输工具,因为运输成本很高,我们希望选择一种运输工具,这种运输工具可以在给定的日期内运输我们所有的产品,但支付的费用最低,因此我们的目标是选择一种能完成这项工作的运输工具,其容量最小(随着运力的增加,我们必须支付的运费会大幅增加)。此外,物品应根据其重量进行移动,最小的物品优先

给定数据:n项,i个对象为Wi,d天 通缉令:c,显示所选车厢的最低载客量

Example :
10 items
weights : 1 2 3 4 5 6 7 8 9 10
5 days

answer : 15
day 1 -> 1,2,3,4
day 2 -> 5,6
day 3 -> 7,8
day 4 -> 9
day 5 -> 10

为了有效地解决这一问题,你应该进行二进制搜索。你可以在SARS上进行二进制搜索,检查你能做的最小值。下面可以看到我的C++解决方案,以便更好地理解。
#include<bits/stdc++.h>
//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
//using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
//typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>ordered_set;

#define fread           freopen("input.txt","r",stdin)
#define fwrite          freopen("output.txt","w",stdout)
#define eb              emplace_back
#define em              emplace
#define pb              push_back
#define Mp              make_pair
#define ff              first
#define ss              second
#define all(a)          a.begin(),a.end()
#define Unique(a)       sort(all(a)),a.erase(unique(all(a)),a.end())
#define FastRead        ios_base::sync_with_stdio(0);cin.tie(0);
#define memo(ara,val)   memset(ara,val,sizeof(ara))
#define II              ( { int a ; read(a) ; a; } )
#define LL              ( { ll a ; read(a) ; a; } )
#define DD              ({double a; scanf("%lf", &a); a;})
#define rep(i,n)        for(int i=0;i<n;i++)
#define rep1(i,n)       for(int i=1;i<=n;i++)
#define rrep(i,a,n)     for(int i=a;i<=n;i++)
#define per(i,n,a)      for(int i=n;i>=a;i--)
#define pf(n)           printf("%lld",n)
#define pfi(n)          printf("%d",n)
#define sp              printf(" ")
#define ln              printf("\n")
#define sc(x)           scanf("%lld",&x)
#define scw(x)          scanf("%I64d",&x)
#define sci(x)          scanf("%d",&x)
#define sc2(x,y)        scanf("%lld %lld",&x,&y)
#define sc3(x,y,z)      scanf("%lld %lld %lld",&x,&y,&z)
#define Found(a, b)     a.find(b) != a.end()
// bool operator< (const node& sx) const { return sx.val < val; }
//set<ll,greater<ll> >st;
//priority_queue<ll , vector<ll> , greater<ll> >
template<class T>inline bool read(T &x){ int c=getchar();int sgn=1;
  while(~c&&c<'0'|c>'9'){if(c=='-')sgn=-1;c=getchar();}
  for(x=0; ~c&&'0'<=c&&c<='9'; c=getchar())x=x*10+c-'0';x*=sgn;return ~c;
}
const ll N = 200005;
const ll MOD = 1e9+7;
ll ara[N], d, n;
bool check(ll carriageCapacity) {
     ll days = 1;
     ll s = 0;
     bool f = true;
     rep1(i, n) {
        s += ara[i];
        if(s > carriageCapacity) {
            days += 1;
            s = ara[i];
        }
     }
     if(days > d) f = false;
     return f;
}

int main(){

     //fread;
     //fwrite;
    n = LL;
    ll sum  = 0;
    rep1(i,n) {
       ara[i] = LL;
       sum += ara[i];
    }
    d = LL;
    ll lo = ara[n], hi = sum, ans;
    while(lo <= hi) {
        ll mid = (lo + hi) >> 1;
        if(check(mid)) {
            hi = mid - 1;
            ans = mid;
        }
        else {
            lo = mid + 1;
        }
    }
    cout << ans << endl;

}
#包括
//#包括
//#包括
使用名称空间std;
//使用名称空间_gnu_pbd;
typedef long-long-ll;
typedef无符号长ull;
双锁相环;
typedef对pii;
//typedef treeordered_套装;
#定义fread freopen(“input.txt”,“r”,stdin)
#定义fwrite-freopen(“output.txt”,“w”,stdout)
#定义电子束位置
#确定电磁侵位
#定义pb推回
#定义Mp make_对
#首先定义ff
#定义ss秒
#定义所有(a)a.开始(),a.结束()
#定义唯一(a)排序(全部(a)),a.erase(唯一(全部(a)),a.end()
#定义FastRead ios_base::与stdio同步(0);cin.tie(0);
#定义memo(ara,val)memset(ara,val,sizeof(ara))
#定义II({int a;读取(a);a;})
#定义LL({lla;read(a);a;})
#定义DD({double a;scanf(“%lf”,&a);a;})

定义了(i,n)(int i=0;i),有效地解决了这个问题,你应该进行二进制搜索。你可以在SARS上进行二进制搜索,检查你能做的最小值。下面可以看到我的C++解决方案,以便更好地理解。
#include<bits/stdc++.h>
//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
//using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
//typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>ordered_set;

#define fread           freopen("input.txt","r",stdin)
#define fwrite          freopen("output.txt","w",stdout)
#define eb              emplace_back
#define em              emplace
#define pb              push_back
#define Mp              make_pair
#define ff              first
#define ss              second
#define all(a)          a.begin(),a.end()
#define Unique(a)       sort(all(a)),a.erase(unique(all(a)),a.end())
#define FastRead        ios_base::sync_with_stdio(0);cin.tie(0);
#define memo(ara,val)   memset(ara,val,sizeof(ara))
#define II              ( { int a ; read(a) ; a; } )
#define LL              ( { ll a ; read(a) ; a; } )
#define DD              ({double a; scanf("%lf", &a); a;})
#define rep(i,n)        for(int i=0;i<n;i++)
#define rep1(i,n)       for(int i=1;i<=n;i++)
#define rrep(i,a,n)     for(int i=a;i<=n;i++)
#define per(i,n,a)      for(int i=n;i>=a;i--)
#define pf(n)           printf("%lld",n)
#define pfi(n)          printf("%d",n)
#define sp              printf(" ")
#define ln              printf("\n")
#define sc(x)           scanf("%lld",&x)
#define scw(x)          scanf("%I64d",&x)
#define sci(x)          scanf("%d",&x)
#define sc2(x,y)        scanf("%lld %lld",&x,&y)
#define sc3(x,y,z)      scanf("%lld %lld %lld",&x,&y,&z)
#define Found(a, b)     a.find(b) != a.end()
// bool operator< (const node& sx) const { return sx.val < val; }
//set<ll,greater<ll> >st;
//priority_queue<ll , vector<ll> , greater<ll> >
template<class T>inline bool read(T &x){ int c=getchar();int sgn=1;
  while(~c&&c<'0'|c>'9'){if(c=='-')sgn=-1;c=getchar();}
  for(x=0; ~c&&'0'<=c&&c<='9'; c=getchar())x=x*10+c-'0';x*=sgn;return ~c;
}
const ll N = 200005;
const ll MOD = 1e9+7;
ll ara[N], d, n;
bool check(ll carriageCapacity) {
     ll days = 1;
     ll s = 0;
     bool f = true;
     rep1(i, n) {
        s += ara[i];
        if(s > carriageCapacity) {
            days += 1;
            s = ara[i];
        }
     }
     if(days > d) f = false;
     return f;
}

int main(){

     //fread;
     //fwrite;
    n = LL;
    ll sum  = 0;
    rep1(i,n) {
       ara[i] = LL;
       sum += ara[i];
    }
    d = LL;
    ll lo = ara[n], hi = sum, ans;
    while(lo <= hi) {
        ll mid = (lo + hi) >> 1;
        if(check(mid)) {
            hi = mid - 1;
            ans = mid;
        }
        else {
            lo = mid + 1;
        }
    }
    cout << ans << endl;

}
#包括
//#包括
//#包括
使用名称空间std;
//使用名称空间_gnu_pbd;
typedef long-long-ll;
typedef无符号长ull;
双锁相环;
typedef对pii;
//typedef treeordered_套装;
#定义fread freopen(“input.txt”,“r”,stdin)
#定义fwrite-freopen(“output.txt”,“w”,stdout)
#定义电子束位置
#确定电磁侵位
#定义pb推回
#定义Mp make_对
#首先定义ff
#定义ss秒
#定义所有(a)a.开始(),a.结束()
#定义唯一(a)排序(全部(a)),a.erase(唯一(全部(a)),a.end()
#定义FastRead ios_base::与stdio同步(0);cin.tie(0);
#定义memo(ara,val)memset(ara,val,sizeof(ara))
#定义II({int a;读取(a);a;})
#定义LL({lla;read(a);a;})
#定义DD({double a;scanf(“%lf”,&a);a;})

#为(inti=0;i定义rep(i,n)Python解决方案如下所示。 使用二进制搜索查找满足给定条件的容器大小。此解决方案的复杂性为O(n*logn)

def发货日期(重量:列表[int],D:int)->int:
def可行(容量)->bool:
天数=1
总数=0
对于以重量表示的重量:
总重量+=重量
如果总容量>容量:#太重,请等待第二天
总数=重量
天数+=1
如果天数>D:#无法在D天内发货
返回错误
返回真值
左、右=最大(重量),总和(重量)
当左<右:
中间=左+(右-左)//2
如果可行(中期):
右=中
其他:
左=中+1
左转

Python解决方案如下所示。 使用二进制搜索查找满足给定条件的容器大小。此解决方案的复杂性为O(n*logn)

def发货日期(重量:列表[int],D:int)->int:
def可行(容量)->bool:
天数=1
总数=0
对于以重量表示的重量:
总重量+=重量
如果总容量>容量:#太重,请等待第二天
总数=重量
天数+=1
如果天数>D:#无法在D天内发货
返回错误
返回真值
左、右=最大(重量),总和(重量)
当左<右:
中间=左+(右-左)//2
如果可行(中期):
右=中
其他:
左=中+1
左转

从可能工作的尽可能小的托架开始(c=(总和Wi)/d).使用的变体将项目放入大小为c的天数中。增加运输的大小,直到其起作用。或类似的情况。示例中的解决方案不是最佳解决方案。例如,通过交换6和7,可以得到更好的解决方案。事实上,即使理论上最小的11也可以实现(1,10)、(2,9)、(3,8)、(4,7)、(5,6)@Henry物品的发送顺序不应改变,这意味着我们不能发送第一件物品和最后一件物品,也不能发送5件物品和7件物品,因为包裹中没有6件物品。从可能有效的最小运输开始(c=(sum Wi)/d).使用的变体将项目放入大小为c的天数中。增加运输的大小,直到其起作用。或类似的情况。示例中的解决方案不是最佳解决方案。例如,通过交换6和7,可以得到更好的解决方案。事实上,即使理论上最小的11也可以实现(1,10)、(2,9)、(3,8)、(4,7)、(5,6)“@Henry物品的发送顺序不应改变,这意味着我们不能在没有订单的情况下发送第一件物品和最后一件物品,或发送5件物品和7件物品