codeforces #38E

来源:互联网 发布:淘宝刷欢乐豆原理2017 编辑:程序博客网 时间:2024/05/23 20:47

题意:有n个弹珠分别位于x轴上的一些位置,你可以选择其中的一些固定住(需要花费ci),当选择完毕之后,从最右面开始,弹珠会依次向左滚动直到遇到被固定住的弹珠(否则视为滚到无穷远处),计算花费+所有弹珠滚动的距离之和的最小值

思路:使用动态规划,首先最左边的弹珠肯定是要被固定住的,接着从左向右考虑每一个弹珠,固定每一个弹珠的花费都是可以直接得到的(花费-右边所有弹珠的个数*该弹珠到它右边相邻的一个弹珠的距离),接着就可以套用0-1背包的模型做了,注意一开始要先将弹珠根据它们的位置排序


AC代码:

#include <stdio.h>#include <climits>#include <algorithm>#include <iostream>typedef long long LL;using namespace std;struct node{LL x,c;}mar[3010];LL dp[3010][3010] = {0};bool cmp(node a,node b){return a.x<b.x;}int main(){int n;scanf("%d",&n);for(int i = 0;i<n;i++) scanf("%I64d%I64d",&mar[i].x,&mar[i].c);sort(mar,mar+n,cmp);for(int i = 1;i<n;i++)dp[0][0]+= mar[i].x-mar[0].x;dp[0][0]+=mar[0].c;for(int i = 1;i<n;i++){dp[i][i] = LLONG_MAX;for(int j = 0;j<i;j++){dp[i][j] = dp[j][j];dp[i][i] = min(dp[i][i],dp[i][j]-(mar[i].x-mar[j].x)*(n-i)+mar[i].c);}}LL ans = LLONG_MAX;for(int i = 0;i<n;i++){ans = min(ans,dp[n-1][i]);//cout << dp[n-1][i] << endl;}printf("%I64d\n",ans);return 0;}

0 0
原创粉丝点击