P3891 [GDOI2014] 采集资源 题解
题面。
看到大家都是两个动态规划的写法,来给大家讲一下只用一次动态规划的写法。
思路
设
从 f[i + b[k]][j - a[k]] = min(f[i + b[k]][j - a[k]] , f[i][j])
,表示招募一个苦工,但注意这个苦工所需资源不能超过
买了苦工后,自然效率变为
如果此时
首先,
在每次枚举完苦工种类后,也需要考虑如果此后一直不买苦工是否会需要更少的时间就能达到
if(i)
{
tme = min(tme , (t - j + i - 1) / i + f[i][j]);
}
明显,当
对于每一个
if(i + j < t)
{
f[i][i + j] = min(f[i][i + j] , f[i][j] + 1);
}
复杂度
请原谅我拙劣的表达,真的尽力了。
代码
#include<bits/stdc++.h>
#define ll long long
#define mod 1000000007
#define fr(i , a , b) for(ll i = a ; i <= b ; ++i)
#define fo(i , a , b) for(ll i = a ; i >= b ; --i)
using namespace std;
inline ll QuickPow(ll a , ll b)
{
if(b == 0)
{
return 1;
}
ll k = QuickPow(a , b>>1);
if(b & 1)
{
return (k * k * a) % mod;
}
return (k * k) % mod;
}
ll n , m , t;
ll tme = 0x3f3f3f3f;
ll a[10000] , b[10000];
ll f[1001][1001];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> t;
memset(f , 0x3f3f3f3f , sizeof(f));
if(m >= t)
{
cout << 0;
return 0;
}
fr(i , 1 , n)
{
cin >> a[i] >> b[i];
}
fr(i , 1 , m)
{
f[0][i] = 0;
}
fr(i , 0 , t)
{
fr(j , 0 , t)
{
fr(k , 1 , n)
{
if(a[k] < j)
{
f[i + b[k]][j - a[k]] = min(f[i + b[k]][j - a[k]] , f[i][j]);
if(i + b[k] >= t)
{
tme = min(tme , f[i][j] + 1);
}
}
}
if(i)
{
tme = min(tme , (t - j + i - 1) / i + f[i][j]);
}
if(i + j < t)
{
f[i][i + j] = min(f[i][i + j] , f[i][j] + 1);
}
}
}
cout << tme;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!