Soratosorato

CF2000F Color Rows and Columns 题解

Sorato·2024-08-15 08:25·57 次阅读

CF2000F Color Rows and Columns 题解

CF2000F Color Rows and Columns 题解

题目大意#

给定 N 个矩形,第 i 个矩形规格为 ai×bi。对这些矩形的单元格涂色,若一个矩形的一行或一列都被涂上了色,则获得 1 的价值。求获得 M 价值至少要涂多少个单元格。

Solve#

考虑 dp。

fi,j 表示前 i 个矩形,恰好获得 j 价值的最小代价。如何状态转移?

如果我钦定第 i 个矩形中恰好获得 k 价值,即涂满的行和列之和为 kj,最小代价 vi,k 是多少?

考虑枚举涂了 x 列,kx 行,则代价为 ax+b(kx)ab,要减去重叠部分。此表达式形如二次函数,复杂度允许,故枚举 x 找到代价最小值 vi,k 即可。

有状态转移:fi,j=mink=0j{fi1,jk+vi,k}。时间复杂度 O(nk2)

Code#

Copy
#include<bits/stdc++.h> using namespace std; #define int long long inline int read() { short f=1; int x=0; char c=getchar(); while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } const int N=1010,M=110; int t,n,m,a,b,f[N][M]; signed main() { t=read(); while(t--) { n=read();m=read(); for(int i=0;i<=n;i=-~i) for(int j=1;j<=m;j=-~j) f[i][j]=1e18; for(int i=1;i<=n;i=-~i) { a=read();b=read(); for(int j=0;j<=m&&j<=a+b;j=-~j) { int mn=1e18; for(int k=max(0ll,j-a);k<=j&&k<=b;k=-~k) mn=min(mn,k*a+(j-k)*b-k*(j-k)); for(int k=j;k<=m;k=-~k) f[i][k]=min(f[i][k],f[i-1][k-j]+mn); } } printf("%lld\n",f[n][m]==1e18?-1ll:f[n][m]); } return 0; }
posted @   Sorato  阅读(57)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
历史上的今天:
2023-08-15 P3629 巡逻 LCA题解
点击右上角即可分享
微信分享提示
目录