复制代码

01分数规划

01分数规划

n个物品,每个物品有两个权值ai,bi,现在要去掉k个 物品,使得剩下的nk个物品 aibi

有最大值,并求出该最大值。

aibi = aiwibiwi (wi = 0 / 1 表示物品是否选择) X

aiwi - X * biwi 0

wi * (ai - X * bi) 0

ai - X * bi 看作物品的新权值,按照权值大小排序,将 nk个加和 看是否 0

现在只需要找到 最大的X 使不等式成立 ,

二分答案 ! 找到 X 的二分区间!

[放弃测试](234. 放弃测试 - AcWing题库)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 2e3 + 50;
int n,k;
int a[N],b[N];
double c[N];
bool check(double x) 
{
    for(int i = 1;  i <= n; i++) 
    c[i] = a[i] - x * b[i];
    sort(c+1,c+n+1);
    double ans = 0;
    for(int i = k + 1; i <= n; i ++)  ans += c[i];
    if(ans < 0) return false;
    else return true;
}
int main()
{
    while(1) {
        scanf("%d%d",&n,&k);
        if(n == 0 && k == 0) break;
        for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
        for(int i = 1; i <= n; i++) scanf("%d",&b[i]);
        double l = 0, r = 1;
        while(l + 1e-5 < r)
        {
            double mid = (l + r) / 2;
            if(check(mid) == true) l = mid;
            else r = mid;
        }
        printf("%.0lf\n",r * 100);
    }
    return 0;
}

[观光奶牛](361. 观光奶牛 - AcWing题库)

有向图环-> SPFA

fiti = fiwitiwi X

wi(fiXti)0
wi(Xtifi)0
令 新边权 为 Xtifi 跑一遍 SPFA 看看 有没有 负环
由于不清楚有向图的起点和连通性,每个点都要 跑一遍,以防错漏负环

#include <iostream>
#include <cstdio>
#include <queue>
using  namespace std;
const int N = 2e4 + 50;
const int INF  = 1e8 + 91;
int n,m;
int f[N];
struct node{
    int from;
    int to;
    int dis;
    int next;
}e[N];
int cnt;
int head[N];
double mapp[N];
void add(int u,int v,int w)
{
    cnt++;
    e[cnt].from = u;
    e[cnt].to =  v;
    e[cnt].dis = w;
    e[cnt].next = head[u];
    head[u] = cnt;
}
bool vis[N];
int num[N];
bool SPFA(double t) 
{
    queue<int> q;
    for(int i = 1; i <= n; i++) {
        vis[i] = true; mapp[i] = INF; num[i] = 0;
        q.push(i);// 关键 
    }
    while(!q.empty())
    {
        int x = q.front();
        vis[x] = false;
        q.pop();
        for(int i = head[x]; i ; i = e[i].next)
        {
            int y = e[i].to;
            double val = e[i].dis * t - f[x];// 新边权 
            if(mapp[x] + val < mapp[y]) 
            {
                mapp[y] = mapp[x] + val;// spfa 最短路 板子
                num[y] = num[x] + 1;
                if(num[y] >= n) return true;// 有 负环 
                if(vis[y] == false) q.push(y);
             }
        }
    }
    return false;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;  i <= n; i++) scanf("%d",&f[i]);
    for(int i = 1; i <= m; i++)
    {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);
    }
    double l = 0, r = 1e3 + 20;
    while(l + 1e-5 < r)
    {
        double mid = (l + r) / 2;
        if(SPFA(mid) == true) l = mid;
        else r = mid;
    }
    printf("%.2f",r);
    return 0;
}
posted @   Elgina  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示