Mice and Holes CodeForces - 797F
Mice and Holes CodeForces - 797F
题意:有n只老鼠和m个洞,都在一个数轴上,老鼠坐标为x[1],...,x[n],洞的坐标为p[1],...,p[m],每个洞能容纳的老鼠为c[1],...,c[m],问所有老鼠都躲到洞里后每只老鼠跑的距离之和的最小值。
分析:
如果不给出洞和老鼠的顺序的话,就需要集合操作,基本就是枚举,很慢不考虑。
因此,按坐标顺序排序洞和老鼠,然后定义状态:ans[i][j]表示前i个洞放前j个老鼠最小距离和。
这么做是由于如果有老鼠跑的路线交叠了,那么就一定不是最好的答案。而先排序后这么定义状态,就隐含了只能是前i-1个洞放前k个老鼠,然后第i个洞放第k+1到第j个老鼠,路线不交叠。
(以下部分自己想不到)
然而实际做的时候不一定能想到,这时一定要大胆尝试(比如试一试排序,很可能一排序就能定义出状态了)。
那么ans[i][j]=min(ans[i-1][j]+0,ans[i-1][j-1]+{ j ~ j 的点到i距离和},ans[i-1][j-2]+{ j-1 ~ j 的点到i距离和}...,ans[i-1][j-c[i]]+{ j-c[i]+1 ~ j 的点到i的距离和})
再看ans[i][j-1]=min(ans[i-1][j-1]+0,ans[i-1][j-2]+{ j-1 ~ j-1 的点到i距离和},...,ans[i-1][j-c[i]-1]+{ j-c[i] ~ j-1 的点到i距离和})
仔细看很像取一个"滑动窗口"中最小值,但形式不可以加速,还是太慢。
因此变形一下:
ans[i][j]=min(ans[i-1][j]+0,ans[i-1][j-1] + 1到j的点到i距离和 - 1到(j-1)的点到i距离和,ans[i-1][j-2] + 1到j的点到i距离和 - 1到(j-2)的点到i距离和,...,ans[i-1][j-c[i]] + 1到j的点到i距离和 - 1到(j-c[i])的点到i距离和)
ans[i][j-1]=min(ans[i-1][j-1]+0,ans[i-1][j-2] + 1到j-1的点到i距离和 - 1到j-2的点到i距离和,...,ans[i-1][j-c[i]-1] + 1到j-1的点到i距离和 - 1到j-c[i]-1的点到i距离和)
也就是,ans[i][j]=1到j的点到i距离和 + min{ans[i-1][j-k] - 1到j-k的点到点i距离和}(0<=k<=c[i])
ans[i][j-1]=1到j-1的点到i距离和 + min{ans[i-1][j-k-1]-1到j-k-1的点到点i距离和}(0<=k<=c[i]-1)
也就是,ans[i][j]=1到j的点到i距离和 + min(ans[i-1][j]-1到j的点到i距离和,...,ans[i-1][j-c[i]]-1到j-c[i]的点到i距离和)
ans[i][j-1]=1到j-1的点到i距离和 + min(ans[i-1][j-1]-1到j-1的地点到i距离和,...,ans[i-1][j-c[i]-1]-1到j-c[i]-1的点到i距离和)
这样就可以每次i变化时用单调队列维护min{ans[i-1][j-..]-..}。
还有,ans[i][..]只跟ans[i-1][..]有关,可以用滚动数组省空间。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;//曾经忘开LL
struct Hole
{
LL p,c;
bool operator<(const Hole& b) const
{
return p<b.p;
}
}h[];
LL n,m;
LL x[];
LL ans[][];
//曾经写错成ans[5010][2]
LL q[],l,r,i1;
LL s1[];//表示前i个洞容纳的总老鼠数量
LL s2[];//s2[j]表示预处理出的1~j的老鼠到i距离和
int main()
{
LL i,j;
scanf("%I64d%I64d",&n,&m);
for(i=;i<=n;i++)
scanf("%I64d",&x[i]);
for(i=;i<=m;i++)
scanf("%I64d%I64d",&h[i].p,&h[i].c);
sort(x+,x+n+);
sort(h+,h+m+);
for(i=;i<=m;i++)
s1[i]=s1[i-]+h[i].c;
memset(ans,0x3f,sizeof(ans));
ans[][]=;//曾经误将ans[0][..]全部置0
if(n>s1[m])
{
printf("-1");
return ;
}
for(i=;i<=m;i++)
{
i1^=;
l=r=;
for(j=;j<=min(s1[i],n);j++)
s2[j]=s2[j-]+abs(x[j]-h[i].p);
//q[r++]=0;
for(j=;j<=min(s1[i],n);j++)//曾经误将初始当做1
{
if(r>l&&q[l]<j-h[i].c) l++;//第j个要考虑的是j-c[i] ~ j,也就是去掉j-c[i]之前的,向单调队列中加入j
while(r>l&&ans[i1^][q[r-]]-s2[q[r-]]>=ans[i1^][j]-s2[j])
r--;
q[r++]=j;
ans[i1][j]=ans[i1^][q[l]]-s2[q[l]]+s2[j];
}
}
printf("%I64d",ans[m%][n]);
return ;
}
upd190422:
这题被超级加强了...加强后的题目:uoj455
稍微改一下可过此题
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
struct P
{
ll x,y;
};
bool operator<(const P &a,const P &b)
{
return a.x>b.x;
}
struct PP
{
int x,w,c;
}p[];
bool operator<(const PP &a,const PP &b)
{
return a.x<b.x;
}
int n,m;
ll ans;
priority_queue<P> q1,q2;
int main()
{
int i;P t;ll v,ts=,t1,t2;
scanf("%d%d",&n,&m);
for(i=;i<=n;++i)
{
scanf("%d",&p[i].x);
p[i].c=-;
}
for(i=;i<=m;++i)
{
scanf("%d%d",&p[i+n].x,&p[i+n].c);
ts+=p[i+n].c;
}
if(n>ts) {puts("-1");return ;}
sort(p+,p+n+m+);
for(i=;i<=n+m;++i)
{
if(p[i].c==-)
{
if(q2.empty()) v=1e11;
else
{
t=q2.top();q2.pop();
v=t.x;
if(t.y!=) q2.push((P){t.x,t.y-});
}
ans+=p[i].x+v;
q1.push((P){-*p[i].x-v,});
}
else
{
t1=;
while(p[i].c && !q1.empty())
{
t=q1.top();v=t.x;
if(p[i].x+p[i].w+v>=) break;
q1.pop();
t2=min(ll(p[i].c),t.y);
t.y-=t2;p[i].c-=t2;
ans+=t2*(p[i].x+p[i].w+v);
t1+=t2;
q2.push((P){-*p[i].x-v,t2});
if(t.y) q1.push(t);
}
if(t1) q1.push((P){-p[i].x-p[i].w,t1});
if(p[i].c) q2.push((P){p[i].w-p[i].x,p[i].c});
}
}
printf("%lld\n",ans);
return ;
}
Mice and Holes CodeForces - 797F的更多相关文章
- AC日记——Mice and Holes codeforces 797f
797F - Mice and Holes 思路: XXYXX: 代码: #include <cmath> #include <cstdio> #include <cst ...
- Codeforces 797 F Mice and Holes
http://codeforces.com/problemset/problem/797/F F. Mice and Holes time limit per test 1.5 ...
- Mice and Holes 单调队列优化dp
Mice and Holes 单调队列优化dp n个老鼠,m个洞,告诉你他们的一维坐标和m个洞的容量限制,问最小总距离.1 ≤ n, m ≤ 5000. 首先列出朴素的dp方程:\(f[i][j] ...
- CF797F Mice and Holes 贪心、栈维护DP
传送门 首先\(\sum c\)有些大,考虑将其缩小降低难度 考虑一个贪心:第一次所有老鼠都进入其左边第一个容量未满的洞(如果左边没有就进入右边第一个未满的洞),第二次所有老鼠都进入其右边第一个容量未 ...
- [Codeforces797F]Mice and Holes
Problem n个老鼠,m个洞,告诉你他们的一维坐标和m个洞的容量限制,问最小总距离. Solution 用dp[i][j]表示前i个洞,进了前j个老鼠的最小代价 dp[i][j]=min(dp[i ...
- [CodeForces-797F]Mice and Holes
题目大意: 在一条直线上,有n个老鼠,m个洞. 每个老鼠i都有一个初始位置x[i]. 每个洞i都有一个固定位置p[i]和容量限制c[i]. 求所有老鼠都进洞的最小距离总和. 思路: 动态规划. 用f[ ...
- Mice and Holes
题意: 有 $n$ 只老鼠和 $m$ 个鼠洞,第 $i$ 只老鼠的坐标为 $x_i$,第 $j$ 个鼠洞的坐标为 $p_j$ ,容量为 $c_j$. 第 $i$ 只老鼠钻进第 $j$ 个鼠洞的距离为 ...
- (分块)Holes CodeForces - 13E
题意 n(n≤105)个洞排成一条直线,第ii个洞有力量值ai,当一个球掉进洞ii时就会被立刻弹到i+ai,直到超出n.进行m(m≤105)次操作: ·修改第i个洞的力量值ai. ·在洞xx上放一个球 ...
- Educational Codeforces Round 19
A. k-Factorization 题目大意:给一个数n,求k个大于1的数,乘积为n.(n<=100,000,k<=20) 思路:分解质因数呗 #include<cstdio> ...
随机推荐
- [Android]Android5.0实现静默接听电话功能
原因: android曾经能够通过AIDL进行静默接听.可是5.0以后就被谷歌给屏蔽了.这时候我们仅仅能通过其它方式实现了. 解决方式: try { Runtime.getRuntime().exec ...
- LeetCode(27)题解:Remove Element
https://leetcode.com/problems/remove-element/ Given an array and a value, remove all instances of th ...
- HDU2255 奔小康赚大钱 【模板】 二分图完美匹配
基本概念 二分图有两个种点:X和Y.X与Y之间存在一些边,每个边有一个权值.现要求求一组X与Y间的通过边实现的一一匹配,使得得到的边权和最大. 总体过程 对每个X节点设置一个顶标Xl,初值为与X相邻的 ...
- SVN命令使用详解【转】
本文转载自:http://blog.sina.com.cn/s/blog_963453200101eiuq.html 1.检出svn co http://路径(目录或文件的全路径) [本地目录全路 ...
- HDU3533 Escape —— BFS / A*算法 + 预处理
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3533 Escape Time Limit: 20000/10000 MS (Java/Others) ...
- tload
tload命令以图形化的方式输出当前系统的平均负载到指定的终端.假设不给予终端机编号,则会在执行tload指令的终端机显示负载情形. 语法 tload(选项)(参数) 选项 -s:指定闲时的刻度: - ...
- Oracle:不同数据库版本导致的Ora-00918问题
今天有同事反映,一个sql在10.0.2.4下面执行是好的,在11.0.2.3报Ora-00918问题. sql语句如下: SELECT kcdm, bjdm, f.kszc, f.jszc FROM ...
- C#方法参数总结
C#中方法的参数的四种类型 C#中方法的参数有四种类型: 1. 值参数类型 (不加任何修饰符,是默认的类型) 2. 引用型参数 (以ref 修饰符声明) 3. ...
- CollectionView垂直缩放卡片布局
实现效果 实现思路 从效果图可以看到变化是,越是往中间滚动的item显示最大,越显眼.而越是往前面,或者越是后面的,反而显示越小,这样就形成了视觉差. 实现的思路就是通过重写在可见范围内的所有item ...
- 并不对劲的bzoj4804:欧拉心算
题目大意 \(t\)(\(t\leq5000\))组询问,每次询问给出\(n\)(\(n\leq10^7\)),求: \[\sum_{i=1}^{n}\sum_{j=1}^{n}\phi(gcd(i, ...