[USACO10NOV]Buying Feed G
2021/10/2 6:40:53
本文主要是介绍[USACO10NOV]Buying Feed G,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
part 1 暴力
不难发现有一个 $\mathcal O(K^2n)$ 的基础 dp:
$$f_{i,j+l}=\min(f_{i,j+l},f_{i-1,j}+(x_i-x_{i-1})jj+c_i*l)$$
这其中 f 代表在第 i 个点已经买了 j+l 个,其中当前第 i 个点买了 l 个,前 i-1 个点买了 j 个的最小价值。
这样的话可以水到 $90pts$,但是如果是联赛的话应该没有这么高的暴力分。
code
#include<bits/stdc++.h> #define int long long #define N 10005 using namespace std; int E,K,f[N],n,c[N],x[N],dp[502][N],sum[N]; struct mm {int c,x,f;}p[N]; namespace AYX { inline bool cmp(mm i,mm j){return i.x<j.x;} inline short main() { scanf("%lld%lld%lld",&K,&E,&n); for(int i=1;i<=n;++i)scanf("%lld%lld%lld",&p[i].x,&p[i].f,&p[i].c); memset(dp,0x3f3f3f3f,sizeof(dp)); dp[1][0]=0; sort(p+1,p+1+n,cmp); p[n+1].x=E;p[n+1].f=K; for(int i=1;i<=n+1;++i)sum[i]=sum[i-1]+p[i].f; for(int i=2;i<=n+1;++i) for(int j=0;j<=min(K,sum[i-1]);++j) for(int l=0;l<=p[i-1].f;++l) { if(l+j>K)break; dp[i][j+l]=min(dp[i][j+l],dp[i-1][j]+p[i-1].c*l+(j+l)*(j+l)*(p[i].x-p[i-1].x)); } printf("%lld\n",dp[n+1][K]); return 0; } } signed main() {return AYX::main(); }
part 2 单调队列优化 dp
对式子进行转换,我们能够得到:
$$f_{i,k}=\min(f_{i,j},f_{i-1,j}+(x_i-x_{i-1})jj-c_ij)+c_ik$$
这样 $c_i\times j$ 会变成一个常数,式子只和 i 和 j 有关。
采用单调队列使复杂度降到 $\mathcal O(Kn)$ 稳稳通过。
当然还可以用二进制优化背包来降复杂度,只不过不如单调队列快。
code
#include<bits/stdc++.h> #define int long long #define N 10005 using namespace std; int E,K,f[N],n,c[N],x[N],dp[502][N],sum[N],dui[N],head,tail; struct mm {int c,x,f;}p[N]; namespace AYX { inline bool cmp(mm i,mm j){return i.x<j.x;} inline int calc(int i,int j) {return dp[i-1][j]+(p[i].x-p[i-1].x)*j*j-j*p[i].c;} inline short main() { scanf("%lld%lld%lld",&K,&E,&n); for(int i=1;i<=n;++i)scanf("%lld%lld%lld",&p[i].x,&p[i].f,&p[i].c); memset(dp,0x3f3f3f3f,sizeof(dp)); dp[0][0]=0; sort(p+1,p+1+n,cmp); for(int i=1;i<=n;++i) { head=1;tail=0; for(int j=0;j<=K;++j) { int val=calc(i,j); while(head<=tail and calc(i,dui[tail])>val)tail--; while(head<=tail and j-p[i].f>dui[head])++head; dui[++tail]=j; dp[i][j]=calc(i,dui[head])+p[i].c*j; } } printf("%lld\n",dp[n][K]+(E-p[n].x)*K*K); return 0; } } signed main() {return AYX::main(); }
这篇关于[USACO10NOV]Buying Feed G的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享