【HDU6024】Building Shops(简单dp)

来源:互联网 发布:小灰狼打印软件注册码 编辑:程序博客网 时间:2024/05/19 20:41

记录一个菜逼的成长。。

题目链接

题目大意:
n个教室,选一些教室建造糖果商店。
每个教室,有一个坐标xi和在这个教室建造糖果商店的花费ci
对于每一个教室,如果这个教室建造糖果商店,花费就是ci,否则就是与坐标在自己前面的建造糖果商店的距离
求最小花费

这题一开始想的贪心,但是是错的。
比如
3
1 1
10 10
11 99

考虑dp
dp[i][1]:=i
dp[i][0]:=i
对于dp[i][1]有如下状态转移
dp[i][1]=min(dp[i1][1],dp[i1][0])
对于dp[i][0]有如下状态转移
枚举上一个建造糖果商店的教室
dp[i][0]=min(dp[i1][0],dp[j][1]+sum)(1j<i)
(sum是第j+1个教室到第i个教室与第j个教室的距离之和)

#include <bits/stdc++.h>using namespace std;#define fi first#define se second#define cl(a,b) memset(a,b,sizeof(a))typedef long long LL;typedef pair<LL,LL> PLL;const int maxn = 3000 + 10;PLL a[maxn];LL dp[maxn][2];int main(){    int n;    while(~scanf("%d",&n)){        cl(dp,0x3f3f3f3f);        for( int i = 1; i <= n; i++ ){            scanf("%lld%lld",&a[i].fi,&a[i].se);        }        sort(a+1,a+1+n);        dp[1][1] = a[1].se;        for( int i = 2; i <= n; i++ ){            dp[i][1] = min(dp[i-1][1],dp[i-1][0]) + a[i].se;            LL tmp = 0;            for( int j = i-1; j > 0; j-- ){                tmp += (i-j) * (a[j+1].fi - a[j].fi);                dp[i][0] = min(dp[j][1]+tmp,dp[i][0]);            }        }        printf("%lld\n",min(dp[n][1],dp[n][0]));    }    return 0;}
0 0