专栏文章
【题解】P6173 [USACO16FEB] Circular Barn P
P6173题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mipacp93
- 此快照首次捕获于
- 2025/12/03 08:45 3 个月前
- 此快照最后确认于
- 2025/12/03 08:45 3 个月前
题意
有顺时针编号的 个房间,房间 有 头奶牛,你需要在这些房间中开 扇门,每个奶牛会从某个门进入,然后顺时针行走到自己的谷仓,求奶牛行走距离总和的最小值。
思路
在一个环上比较难考虑,因此我们断环为链,这里需要 的时间复杂度。
设 为前 个房间开 扇门时奶牛行走距离的总和,则有转移方程如下:
其中 为在房间 开门,房间编号为 的奶牛的行走距离总和,可以 预处理出来。
这个做法是 的,无法通过此题,但是可以通过此题的弱化版。
通过打表可以发现对于 有 ,证明如下:
满足四边形不等式,故满足决策单调性,考虑使用分治优化,最终时间复杂度为 ,可以通过此题。
代码
CPP#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e3+5,M=15,inf=(int)4e18+5;
int a[N<<1],w[N<<1][N<<1],dp[N][M];
void solve(int bgn,int id,int l,int r,int lpt,int rpt)
{
if(l>r)return;
int mid=l+r>>1,opt;
for(int i=lpt;i<=min(mid,rpt);i++)
{
int val=dp[i][id-1]+w[i+bgn][mid+bgn-1];
if(dp[mid][id]>val)dp[mid][id]=val,opt=i;
}
solve(bgn,id,l,mid-1,lpt,opt),solve(bgn,id,mid+1,r,opt,rpt);
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i],a[i+n]=a[i];
for(int i=1;i<=(n<<1);i++)
for(int j=i+1;j<=(n<<1);j++)
w[i][j]=w[i][j-1]+a[j]*(j-i);
int ans=inf;
for(int i=1;i<=n;i++)
{
for(int j=1;j<N;j++)
for(int k=0;k<M;k++)
dp[j][k]=inf;
for(int j=1;j<=m;j++)solve(i,j,0,n,0,n);
ans=min(ans,dp[n][m]);
}
cout<<ans;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...