羅区P4377 [USACO18OPEN]タレントショー+スコア計画

分数計画

スコア計画がある画分の比に関連する問題に対処するために使用することができます。

そして、スコアは、一般的に独立した計画問題を設定していないが、グラフ理論、一緒にネットワークフローアルゴリズムへとDP。

基本的なアプローチは半分を通じて一般的です。

私たちは皆知っているハーフタイトルは、それがどのような最小または最大要求、半分は何か。

単調である最小値または最大値。

電流最大値が設定されている\(MAXN \)このような比その比がある場合、\(MAXN \)大きい、\(Y / X> MAXN \)が簡略化を与えるために、:\(YX * MAXN> 0 \)

あなたは答えを更新することができます。二分法が成立している(すなわち\(MAXN \)より大きい\(X * Y-MAXN \) が小さく、回答を更新することがより困難になります。

そして2つのチェックポイントは、ソートすることによって決定することができる\(Y [I] -x [ I] * MAXNの\)の最大値、及び、直接最大貪欲を取り、最終的に0よりも大きいか否かを判断します

このトピック

重量制限があるため、この問題は、貪欲発注要件については、それは、最大値とはみなされません、バックパックを使用することが可能です。

重量はそれが、値であり、オリジナルデータの量である\(Y [I] -X- [I] * MAXN \) 転写時に必要なすべての重量は、最終的なWに転送さWよりも大きいです

最後に、統計的な利便性。

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, m, dp[100100];
struct dat {        
    int w, t;       
    int bizhi;      
}data[1001000];     
bool check(int mid) 
{                   
    memset(dp, 128, sizeof(dp));
    dp[0] = 0;      
    for (int i = 1; i <= n; i++)
        data[i].bizhi = data[i].t - mid * data[i].w;
    int ha = dp[m]; 
    for (int i = 1; i <= n; i++)
        for (int j = m; j >= 0; j--)
            if (dp[j] != ha)
                dp[min(m, j + data[i].w)] = max(dp[min(m, j + data[i].w)], dp[j] + data[i].bizhi);//取min的意义是为了让所有质量都大于m的都转移到一个地方 
    if (dp[m] >= 0) return 1;//如果存在一个价值使得能够>=0即满足条件,则该mid可以,寻找更大的 
    else return 0;  
}                   
signed main()                                               
{                   
    scanf("%lld%lld", &n, &m);
    for (int i = 1; i <= n; i++)
        scanf("%lld%lld", &data[i].w, &data[i].t), data[i].t *= 1000;
    int l = 0, r = 150000, ans;
    while (l <= r)  
    {
        int mid = (l + r) / 2;
        if (check(mid))     
            l = mid + 1, ans = mid;
        else
            r = mid - 1;
    }
    printf("%lld", ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/liuwenyao/p/11222416.html