题意

戳这里

吐槽

听同学说今年\(pjT3\)很难,于是就去看了下。

一眼斜率优化...为什么\(n,m\)这么小啊...

感觉这题出的还是不错的。

Solution

首先我们先转化一波题意:给出数轴上\(n\)个点,让你选择若干个两两距离大于等于\(m\)的点,使得每个点到右边第一个你选的点的距离和最小。

大力\(dp\),发现可以斜率优化。

\(pj\)会考斜率优化?

冷静一波,显然每个点的决策肯定在\([i-m*2,i-m]\)之间...

所以好像直接\(O(max(t_i)*m)\)转移常数小并不会\(T\)?

至少我\(Luogu\)数据过了...

#include<bits/stdc++.h>
#define For(i,x,y) for (register int i=(x);i<=(y);i++)
#define Dow(i,x,y) for (register int i=(x);i>=(y);i--)
#define cross(i,u) for (register int i=first[u];i;i=last[i])
using namespace std;
typedef long long ll;
inline ll read(){
ll x=0;int ch=getchar(),f=1;
while (!isdigit(ch)&&(ch!='-')) ch=getchar();
if (ch=='-'){f=-1;ch=getchar();}
while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int N = 1010, maxn = 5000110;
int n,m,Max,a[N],sum[maxn],Sum[maxn],dp[maxn];
bool vis[maxn];
inline void solve(){
For(i,0,Max){
dp[i]=Sum[i]*i-sum[i];
For(j,max(0,i-2*m),i-m){
int cnt=Sum[i]-Sum[j];
dp[i]=min(dp[i],dp[j]+cnt*i-sum[i]+sum[j]);
}
}
int ans=1e9;
For(i,Max-m,Max) ans=min(ans,dp[i]);
printf("%d",ans);
}
int main(){
n=read(),m=read();
For(i,1,n) a[i]=read(),Max=max(Max,a[i]),Sum[a[i]]++,sum[a[i]]+=a[i];
Max+=m;
For(i,1,Max) sum[i]+=sum[i-1],Sum[i]+=Sum[i-1];
solve();
}

再冷静一波...好像有很多状态是没用的?

如果一个点前面的\(m\)个点中都没有给出的点那么\(dp_i=dp_{i-m}\)...

然后算下复杂度...好像是\(O(nm+max(t_i))\)

#include<bits/stdc++.h>
#define For(i,x,y) for (register int i=(x);i<=(y);i++)
#define Dow(i,x,y) for (register int i=(x);i>=(y);i--)
#define cross(i,u) for (register int i=first[u];i;i=last[i])
using namespace std;
typedef long long ll;
inline ll read(){
ll x=0;int ch=getchar(),f=1;
while (!isdigit(ch)&&(ch!='-')) ch=getchar();
if (ch=='-'){f=-1;ch=getchar();}
while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int N = 1010, maxn = 5000110;
int n,m,Max,a[N],sum[maxn],Sum[maxn],dp[maxn];
inline void solve(){
For(i,0,Max){
dp[i]=Sum[i]*i-sum[i];
if (i>m&&Sum[i]-Sum[i-m]==0){dp[i]=dp[i-m];continue;}
For(j,max(0,i-2*m),i-m){
int cnt=Sum[i]-Sum[j];
dp[i]=min(dp[i],dp[j]+cnt*i-sum[i]+sum[j]);
}
}
int ans=1e9;
For(i,Max-m,Max) ans=min(ans,dp[i]);
printf("%d",ans);
}
int main(){
n=read(),m=read();
For(i,1,n) a[i]=read(),Max=max(Max,a[i]),Sum[a[i]]++,sum[a[i]]+=a[i];
Max+=m;
For(i,1,Max) sum[i]+=sum[i-1],Sum[i]+=Sum[i-1];
solve();
}

口胡

不难发现最后有用的点数是\(nm\)...

我们把这\(nm\)个点抠出来,基排一下,然后直接斜率优化\(dp\)应该能做到优秀的\(O(nm)\)的复杂度。

给我把nm开到1000w,ti开到1e9

\(upd:\)我第二个复杂度好像算错了...应该是\(O(nm^2+max(t_i))\)

最新文章

  1. 2. K线学习知识二
  2. Office 365常见问题解答(第一期)
  3. 在博客中使用LaTeX插入数学公式
  4. C#调用LUA函数
  5. create dll project based on the existing project
  6. 记一次小团队Git实践(下)
  7. selenium 使用笔记
  8. Spring+Mybatis+jQuery.Pagination.js异步分页及JsonConfig的使用
  9. instanceof 和 构造函数
  10. SQL FOR XML PATH 用法
  11. 基于JDK 8的Dubbo Admin
  12. 使用Visual Studio创建图片精灵(Image Sprite)——Web Essential
  13. net core中动态给log4net添加日志类型
  14. http2
  15. Pytorch 入门之Siamese网络
  16. STM32 逐次逼近寄存器型(SAR)模拟数字转换器(ADC)
  17. [转]sql server 常用脚本(日常查询所需)
  18. TP5 中引入第三方类库
  19. stopPropagation()阻止事件的冒泡传递
  20. G1 Garbage Collector and Shenandoah

热门文章

  1. 支付宝hr终面,忐忑的等待结果
  2. 事件,继承EventArgs带有参数的委托
  3. C# 序列化高级用法
  4. 爬虫基础---HTTP协议理解、网页的基础知识、爬虫的基本原理
  5. unity 优秀开源项目
  6. Qt软件打包发布(QT5.4.1(msvc2013_64_opengl),Win7 64bit)
  7. 移动端默认meta标签
  8. ASP .Net Core系统部署到 CentOS7 64 具体方案
  9. C++静态成员的应用
  10. 开启nginx目录文件列表功能