CF2023D

CF2023D

Tags:

  • DPStateShrink 动态规划状态缩减,只计算有效状态

题解:

这个题目的问题可以转化为:

选择一个子集 ,最大化他的贡献:

E=(∑iwi)∏ipi100 E=(\sum_{i}w_i) \prod_{i}\frac{pi}{100} E=(i∑wi)i∏100pi

显然当p为100时 ,一定会全选

当p不是100时:

我们令

Eodd=W∗Q E_{odd}=W*Q Eodd=W∗Q

假如我们删除游戏 qiq_iqi wiw_iwi :

Enew=(W+wi)Q∗qi E_{new}=(W+w_i){Q}*{q_i} Enew=(W+wi)Q∗qi

如果删除后更好 那么有

(W+wi)Q∗qi<W∗Qwi∗qi<W∗(1−qi) (W+w_i){Q}*{q_i}<W*Q\\ w_i*q_i<W*(1-q_i)\\ (W+wi)Q∗qi<W∗Qwi∗qi<W∗(1−qi)

根据

wi∗pi<=200000那么W∗(100−pi)>200000 w_i*p_i<=200000\\ 那么\\ W*(100-p_i)>200000 wi∗pi<=200000那么W∗(100−pi)>200000

因此最终W的上界也在200000左右

由于w是存在上界的 ,而且根据我们的直觉,因为概率是累乘的,因此最终选择的物品不会很多,不然累乘后权重会很小

对于同一个p,显然我们只会选择w最大的几个前缀元素

假设我们选择了c个概率为p的元素,那么设其中权重最小的为w_c

如果删除这个最小的元素

原来的期望为WQ 删除后为(W-w_c)Q/q;

最优的时候删除不会更好

WQ>(W−wc)Q/qwc>W(1−q)因为c个wc的总权重为cwc那么W>=cwcwc>=cwc(1−q)c<=1/(1−q)c<=100/(100−p) WQ>(W-w_c)Q/q\\ w_c>W(1-q)\\ 因为c个w_c的总权重为cw_c 那么W>=cw_c\\ w_c>=cw_c(1-q)\\ c<=1/(1-q)\\ c<=100/(100-p) WQ>(W−wc)Q/qwc>W(1−q)因为c个wc的总权重为cwc那么W>=cwcwc>=cwc(1−q)c<=1/(1−q)c<=100/(100−p)

那么也就是说,每个p最多选择100/(100-p) 个元素最为候选

那么最多的元素个数就是

∑i=199100100−i约等于482 \sum_{i=1}^{99}\frac{100}{100-i} 约等于482 i=1∑99100−i100约等于482

因此我们只需要每个概率的若干个元素候选,然后进行01背包即可

令DPi表示W为i的时候,可以获得的最大的概率乘积

code:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2.1e5+5;


priority_queue<int>q[101];
double d[N];
void solve() {
    int n;
    cin>>n;
    d[0]=1;
    int k=0;
    for(int i=0;i<n;i++){
        int x,y;
        cin>>x>>y;
        if(x==100){
            k+=y;
        }else {
            q[x].push(y);
        }
    }
    for(int i=1;i<=99;i++){
        for(int y=100/(100-i);y&&q[i].size();y--){
            int x=q[i].top();
            q[i].pop();
            for(int j=N-1;j>=x;j--){
                d[j]=max(d[j],d[j-x]*i/100);
            }
        }
    }
    double ans=0;
    for(int i=0;i<N;i++){
        ans=max(ans,(i+k)*d[i]);
    }
    cout<<setprecision(7)<<fixed<<ans<<'\n';
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
   
    int t=1;
    // cin>>t;
    while(t--)solve();
    return 0;
}
相关推荐
微尘hjx7 小时前
【ByteTrack 04】多轨迹算法ByteTrack改进点
算法·yolo·目标检测·目标跟踪·bytetrack·ultralytics·车跟踪
dtq04248 小时前
C++小案例 - 日志实战
开发语言·c++
码匠许师傅9 小时前
【C++三方组件】Qt 概览:桌面 C++ 的事实标准与许可证三轨
开发语言·c++·qt
码匠许师傅10 小时前
【C++三方组件】POCO:跨平台系统编程全家桶
开发语言·c++
小蒋观天下11 小时前
雷击与浪涌防护:前端SPD选型、接地网误区,接地不当反而引入干扰
深度学习·算法·机器学习
lvwangshu11 小时前
P15569 [COCI 2025/2026 #5] 结构 / Struktura 题解
矩阵·题解·dp·推导题·矩阵加速
WBluuue12 小时前
数据结构与算法:分块(一):块状数组、块状链表
数据结构·c++·算法·链表
澳鹏Appen14 小时前
澳鹏重磅发布ExamOCRBench:面向端到端试卷判分的多任务基准
算法·benchmark·基准评测
必须得开心呀14 小时前
字节序大小端科普
c++·程序人生