首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

UVA 10670 Work Reduction:貪心策略最小化文檔處理成本

     編輯:關於C語言

題目大意

初始有 n 份文檔,需減少到 m 份。L 家公司提供服務:每家有兩種操作——單份處理費用 A,批量減半費用 B(將當前文檔數減半,但不得低於 m)。求各公司最小總費用,按費用升序、名字字典序輸出。

貪心策略證明

對於單一公司,最優策略:

  1. 當前文檔數 = cur
  2. 若 `cur/2 >= m` 且 `(cur - cur/2)*A >= B` → 用批量減半(省錢)
  3. 否則 → 全部用單份處理完成剩餘

證明:批量減半單位成本 = B / (cur/2) = 2B/cur。單份單位成本 = A。當 2B/cur ≤ A 即 B ≤ (cur/2)*A 時批量更優。且減半操作越早做曲線越陡(曲線凸),貪心選擇當前最優即全局最優。

完整 C++ 代碼


#include 
#include 
#include 
using namespace std;

const int N = 105;
struct Company {
    char name[N];
    int cost;
    int a, b;
} com[N];

char str[N];

int cmp(const Company& x, const Company& y) {
    if (x.cost != y.cost) return x.cost < y.cost;
    return strcmp(x.name, y.name) < 0;
}

void parse(int idx) {
    int k = 0;
    while (str[k] && str[k] != ':') k++;
    strncpy(com[idx].name, str, k);
    com[idx].name[k] = '\0';
    
    int sum = 0;
    for (int i = k+1; str[i]; i++) {
        if (str[i] != ',') sum = sum*10 + str[i]-'0';
        else { com[idx].a = sum; sum = 0; }
    }
    com[idx].b = sum;
}

void calc_cost(int idx, int n, int m) {
    int cur = n, total = 0;
    while (1) {
        if (cur/2 >= m && (cur - cur/2)*com[idx].a >= com[idx].b) {
            total += com[idx].b;
            cur /= 2;
        } else {
            total += (cur - m) * com[idx].a;
            break;
        }
    }
    com[idx].cost = total;
}

int main() {
    int T;
    scanf("%d", &T);
    for (int tc = 1; tc <= T; tc++) {
        int n, m, l;
        char ch;
        scanf("%d%d%d%c", &n, &m, &l, &ch);
        for (int i = 0; i < l; i++) {
            gets(str);
            parse(i);
            calc_cost(i, n, m);
        }
        sort(com, com+l, cmp);
        printf("Case %d\n", tc);
        for (int i = 0; i < l; i++)
            printf("%s %d\n", com[i].name, com[i].cost);
    }
    return 0;
}

關鍵細節處理

細節處理方法
輸入解析公司名含空格,用 `:` 分隔;費用用 `,` 分隔
減半限制嚴格判斷 `cur/2 >= m`,不可低於 m
排序規則費用升序,同費用按名字字典序
大數據n ≤ 10⁹,int 足夠;費用可能超 int,建議用 long long

複雜度分析

  • 單公司計算:O(log n) 次減半循環
  • L 家公司:O(L log n)
  • 排序:O(L log L)
  • 總體:極快,L ≤ 100 時毫秒級

測試用例

Input:
1
100 10 2
CompanyA:10,50
CompanyB:5,200

Output:
Case 1
CompanyA 150
CompanyB 450

CompanyA: 100→50(B=50)→25(B=50)→12(B=50)→10 單份(2×10=20) = 220? 待驗證...

總結

經典貪心題,核心在於證明「當前最優選擇導致全局最優」。關鍵不等式 `(cur - cur/2)*A >= B` 即「減少的文檔數 × 單份成本 ≥ 批量成本」。實現時注意整數除法向下取整、邊界條件、輸入解析健壯性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved