01分数规划
01分数规划
有个物品,每个物品有两个权值,,现在要去掉个 物品,使得剩下的个物品
有最大值,并求出该最大值。
= ( = 0 / 1 表示物品是否选择)
- *
* ( - * )
将 - * 看作物品的新权值,按照权值大小排序,将 个加和 看是否
现在只需要找到 最大的 使不等式成立 ,
二分答案 ! 找到 的二分区间!
[放弃测试](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
=
令 新边权 为 跑一遍 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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?