CF799D题解
CF799D
题意
给定一个长宽为
解析
这题算是一道有趣的背包题。
由于
我们可以将操作数从大到小进行排序,设
初始化
在每次计算转移之后对
另外,观察每次转移时都只和
代码
#include <bits/stdc++.h>
#define LL long long
#define pii pair<int, int>
#define pll pair<LL, LL>
using namespace std;
vector<LL> dp(100005, 0);
LL a[100005];
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
LL h0, w0, h, w, n;
cin >> h0 >> w0 >> h >> w >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
//判定是否已符合条件
if (h >= h0 && w >= w0 || h >= w0 && w >= h0)
{
cout << "0\n";
return 0;
}
sort(a + 1, a + n + 1, greater<LL>());
if (h >= h0 || h >= w0 || w >= h0 || w >= w0) //判断有一条边已符合条件的情况
{
a[0] = 1;
for (int i = 1; i <= n; i++)
a[i] *= a[i - 1];
int ans = n + 5;
if (h >= h0)
{
for (int i = 1; i <= n; i++)
if (w * a[i] >= w0)
{
ans = min(ans, i);
break;
}
}
if (h >= w0)
{
for (int i = 1; i <= n; i++)
if (w * a[i] >= h0)
{
ans = min(ans, i);
break;
}
}
if (w >= h0)
{
for (int i = 1; i <= n; i++)
if (h * a[i] >= w0)
{
ans = min(ans, i);
break;
}
}
if (w >= w0)
{
for (int i = 1; i <= n; i++)
if (h * a[i] >= h0)
{
ans = min(ans, i);
break;
}
}
cout << (ans > n ? -1 : ans) << "\n";
return 0;
}
dp[w] = h; //dp数组初始化
for (int i = 1; i <= n; i++)
for (int j = max(w0, h0); j >= w; j--)
{
dp[min(j * a[i], max(w0, h0))] = max(dp[j], dp[min(j * a[i], max(w0, h0))]);
dp[j] *= a[i];
if (j * a[i] >= w0 && dp[min(j * a[i], max(w0, h0))] >= h0 || j >= w0 && dp[j] >= h0) //判断正放目标矩形的情况
{
cout << i << "\n";
return 0;
}
if (j * a[i] >= h0 && dp[min(j * a[i], max(w0, h0))] >= w0 || j >= h0 && dp[j] >= w0) //判断旋转目标矩形的情况
{
cout << i << "\n";
return 0;
}
}
cout << "-1\n";
}
最后祝各位顺利AC。>w<
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效