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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

美团--订单分配

發布時間:2024/4/11 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 美团--订单分配 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

美團–訂單分配

文章目錄

    • 美團--訂單分配
    • 一、題目描述
    • 二、分析
    • 三、代碼

一、題目描述

打車派單場景, 假定有N個訂單, 待分配給N個司機。每個訂單在匹配司機前,會對候選司機進行打分,打分的結果保存在N*N的矩陣A, 其中A[i][j] 代表訂單i司機j匹配的分值。

假定 每個訂單只能派給一位司機,司機只能分配到一個訂單。求最終的派單結果,使得匹配的訂單和司機的分值累加起來最大,并且所有訂單得到分配。

  • 輸入描述:
第一行包含一個整數N,2≤N≤10。第二行至第N+1行包含N*N的矩陣。
  • 輸出描述:
輸出分值累加結果和匹配列表,結果四舍五入保留小數點后兩位 (注意如果有多組派單方式得到的結果相同,則有限為編號小的司機分配編號小的訂單, 比如:司機1得到1號單,司機2得到2號單,就比司機1得到2號單,司機2得到1號單要好)輸入例子1: 3 1.08 1.25 1.5 1.5 1.35 1.75 1.22 1.48 2.5輸出例子1: 5.25 1 2 2 1 3 3例子說明1: 第一行代表得到的最大分值累加結果5.25,四舍五入保留兩位小數;第二行至第四行代表匹配的結果[i j],其中i按行遞增:訂單1被派給司機2,訂單2被派給司機1,訂單3被派給司機3。使得 A12+ A21+ A33= 1.25 + 1.5 + 2.5 = 5.25在所有的組合中最大。

二、分析

  • 注意題中的一個條件“每個訂單只能派給一位司機,司機只能分配到一個訂單”,因為N*N的矩陣A中保存著每個顧客對司機的打分情況,而A[i][j] 代表訂單i司機j匹配的分值
  • 這就意味著我們在A數組中進行選擇的時候每一行每一列只能選擇一個
  • 那么這個問題就和n皇后問題、全排列問題基本上是一致的了,是一個典型的回溯算法的思路,求所有排列當中結果最大的一種情況
  • 直接看代碼:

三、代碼

#include <iostream> #include <algorithm> #include <string> #include <vector> #include <stack> #include <queue> using namespace std;void backTrack(vector<vector<double>>& num,vector<bool>&used, vector<int>& pre,vector<int>& cur,double curProfit, double&preProfit, int n, int pos) {//如果pos == n 說明行數已經達到n行,所有的行都已經選完,是一種結果if (pos == n) {//全局找最大,判斷是否出現更優解if (curProfit > preProfit) {//更新當前最大的和preProfit = curProfit;//數組賦值,將這個最優解的數組賦值給pre,最后用來輸出pre = cur; }return;}//枚舉第pos行的每一列for (int i = 0; i < n; i++){//改行必須在之前沒有被選擇使用過,必須滿足題意if (!used[i]) // 標記第 i列,下一次第i列就不能選擇了{//代表本次選擇pos行的i列元素,進行標記本次遞歸的選擇位置//因為可能出現本次選擇是最優的情況,所以需要保存cur[pos] = i; // 記錄每一個 pos行對應的列數i,下面的就是回溯過程//代表當前的評分和加上本次的選擇//同理和cur一樣都要保存curProfit += num[pos][i];//代表著第i例被使用過,下次不能在選擇第i列used[i] = true;backTrack(num,used,pre,cur, curProfit, preProfit, n, pos + 1);//撤銷選擇curProfit -= num[pos][i];//撤銷標記used[i] = false;}} }int main() {int n;while (cin >> n){vector<vector<double>> vvd(n, vector<double>(n));for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){cin >> vvd[i][j];}}vector<int> pre(n); // 記錄最優解的每個值 所在的 列數vector<int> cur(n); // 列數加入數組vector<bool> used(n); // 標記數組, 因為一列只能選擇一個double preProfit = INT_MIN; // 全局的最大值double curProfit = 0.0; // 當前的最大值int pos = 0; // pos就是行數,pos到達一行,就選y值就可以了backTrack(vvd, used, pre, cur, curProfit, preProfit, n, pos); //打印結果printf("%4.2f\n",preProfit);//cout << preProfit << endl;for (int i = 0; i < pre.size(); i++){cout << i + 1 << " " << pre[i] + 1 << endl;}} }

總結

以上是生活随笔為你收集整理的美团--订单分配的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。