题目大意:一条直线上,有n个教室,现在我要在这些教室里从左到右地建设一些作为糖果屋,每个教室都有自己的坐标xi 和建造糖果屋的费用ci ,如果在这里建造一个糖果屋,那么花费ci ,如果不建造糖果屋,则花费是当前教室的坐标与左边最靠近当前教室的糖果屋坐标之差,问最小花费
dp的思路应该是很明显的
dp[i][1]代表第i个教室建立商店的最小花费,dp[i][0]代表第i个教室不建立商店的最小花费
dp[i][1] = min(dp[i - 1][0] , dp[i - 1][1]) + cost[i]
dp[i][0] = min(dp[j][1] + 距离代价)
其中距离代价是第 j + 1 个教室到第 i 个教室的所有点到第 j 个教室的距离之和
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
ll x,y;
}t[3010];
int n;
ll dp[3010][2];
bool cmp(node k,node l)
{
return k.x < l.x;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i = 1;i <= n; ++i)
scanf("%lld%lld",&t[i].x,&t[i].y);
sort(t + 1,t + n + 1,cmp);
dp[1][0] = dp[1][1] = t[1].y;
for(int i = 2;i <= n; ++i)
{
dp[i][1] = min(dp[i - 1][0],dp[i - 1][1]) + t[i].y;
dp[i][0] = dp[i - 1][1] + t[i].x - t[i - 1].x;
ll sum = t[i].x - t[i - 1].x;
ll k = 1;
for(int j = i - 2;j >= 1; --j)
{
sum += (t[j + 1].x - t[j].x) * (++k);
dp[i][0] = min(dp[i][0],dp[j][1] + sum);
}
}
printf("%lld\n",min(dp[n][0],dp[n][1]));
}
return 0;
}