问题描述
输入格式
输出格式
样例输入
3
1 2
2 3
3 4
4
1 7
3 1
5 10
6 1
样例输出
5
11
题解
题目大意:
N间教室坐落在一维坐标轴上,每间教室有一个坐标。现在小Q想在这n件教室中建几个糖果屋。
总费用由两部分组成——在第i间教室建一个糖果屋需要花费c[i],对于每间没有糖果屋的教室,它到其左边的最近的有糖果屋的教室的距离会被加到那间糖果屋的费用中。显然,如果一间教室没有糖果屋,那么它的左边一定要有一间糖果屋。
现在小Q想知道怎么建糖果屋使得花费最小。请写一个程序帮助他。
输入:
输入包括多组数据且不超过10组。
每组数据第一行有一个整数n(1<=n<=3000)表示教室的个数。
接下来n行,每行有两个整数xi,ci,(-109<=xi,ci<=109),表示第i间教室的坐标和在这间教室建一个糖果屋的费用。
数据保证任意两间教室没有相同的坐标。
输出:
对于每组数据,输出一行包括一个整数,表示最小费用。
设f[i][j]表示从左到右前i间教室,最右边的有糖果屋的教室教室为第j间教室的最小费用。
显然第一间教室一定要建糖果屋,则f[1][1]=c[1],对于第i间教室,如果不建糖果屋,则前i-1间教室最靠右的有糖果屋的教室的位置对f[i][j]有影响,其对总费用的贡献为第i间教室到第j间教室的距离,即f[i][j]=f[i-1][j]+x[i]-x[j];如果建糖果屋,其贡献为c[i],且前i-1间教室最靠右的有糖果屋的教室的位置对f[i][i]没有影响,此时为使总费用最小,应选择最小的f[i-1][k](1<=k<i)转移过来,即f[i][i]=min(f[i-1][k])+c[i];
整理得
f[1][1]=c[1]
f[i][j]=f[i-1][j]+x[i]-x[j](1<=j<i)
f[i][i]=min(f[i-1][k])+c[i](1<=k<i)
1 #include <algorithm> 2 #include <cstdio> 3 int n; 4 long long f[3005][3005],ans; 5 struct node{ 6 int x,c; 7 }a[3005]; 8 bool cmp(node y,node z) 9 { 10 return y.x<z.x; 11 } 12 int main() 13 { 14 int i,j,p; 15 while (scanf("%d",&n)!=EOF) 16 { 17 for (i=1;i<=n;i++) 18 scanf("%d%d",&a[i].x,&a[i].c); 19 std::sort(a+1,a+n+1,cmp); 20 f[1][1]=a[1].c; 21 for (i=2;i<=n;i++) 22 { 23 for (j=1;j<i;j++) 24 f[i][j]=f[i-1][j]+a[i].x-a[j].x; 25 f[i][i]=f[i-1][1]; 26 for (j=2;j<i;j++) 27 if (f[i-1][j]<f[i][i]) 28 f[i][i]=f[i-1][j]; 29 f[i][i]+=a[i].c; 30 } 31 ans=f[n][1]; 32 for (i=2;i<=n;i++) 33 if (f[n][i]<ans) 34 ans=f[n][i]; 35 printf("%lld ",ans); 36 } 37 return 0; 38 }