【数学,DP】AcWing 232. 守卫者的挑战
这题看起来不难然而一堆细节。。
分析
首先不难看出这是一个类似于背包的 dp 问题。
考虑状态的设计: 表示当前考虑到第 个挑战,当前背包剩余容量为 ,前 个挑战中已经成功了 个。
那么我们可以进一步写出转移方程:
- 第 个挑战失败时:
- 第 个挑战成功时:
接下来就是细节问题了:
约定 为地图残片的数量。
- 首先,注意到 会非常大,直接开数组自然不行,事实上当背包容量 的时候能够保证装下所有的地图残片,因此我们可以对状态表示进行调整:对于 表示当前背包剩余容量 , 定义不变。
- 其次,因为我们是对挑战直接进行 的扫描,有可能在过程中出现背包容量为负的情况,但是我们不能直接舍弃这类状态,因为有可能在未来这样的状态可以转移到背包容量为正的情况,那么我们需要想办法将这类状态也保存,具体做法是:将 整体加上一个 的偏移量(类似于将数轴平移)。
// Problem: 守卫者的挑战
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/234/
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define all(x) (x).begin(), (x).end()
inline void read(int &x){
int s=0; x=1;
char ch=getchar();
while(ch<'0' || ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0' && ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=220;
int n, L, K, V;
double p[N];
int w[N];
int main(){
cin>>n>>L>>K;
rep(i,1,n) cin>>p[i], p[i]/=100;
rep(i,1,n){
read(w[i]);
if(w[i]==-1) V++;
}
K=min(V, K);
double f[n+1][V<<1|1][n+1];
memset(f, 0, sizeof f);
f[0][V+K][0]=1;
rep(i,1,n){
rep(j,0,V<<1) rep(k,0,n){
f[i][j][k]+=(1.0-p[i])*f[i-1][j][k];
if(j+w[i]>=0 && k<n) f[i][min(j+w[i], V<<1)][k+1]+=p[i]*f[i-1][j][k];
}
}
double res=0;
rep(i,V,V<<1) rep(j,L,n) res+=f[n][i][j];
printf("%.6lf\n", res);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
2021-02-15 【DP】区间DP入门