BZOJ2020: [Usaco2010 Jan]Buying Feed II

【传送门:BZOJ2020


简要题意:

  约翰开车回家,遇到了双十一节,那么就顺路买点饲料吧。回家的路程一共有E 公里,这一路上会经过N 家商店,第i 家店里有Fi 吨饲料,售价为每吨Ci 元。约翰打算买K 吨饲料,他知道商家的库存是足够的,至少所有店的库存总和不会少于K。除了购买饲料要钱,运送饲料也是要花油钱的,约翰的卡车上如果装着X 吨饲料,那么他行驶一公里会花掉X 元,行驶D 公里需要DX 元。已知第i 家店距约翰所在的起点有Xi 公里,那么约翰在哪些商店买饲料运回家,才能做到最省钱呢?


输入格式:

  • 第一行:三个整数K,E 和N,1 ≤ K ≤ 100, 1 ≤ E ≤ 350, 1 ≤ N ≤ 100

  • 第二行到第N + 1 行:第i + 1 行有三个整数Xi,Fi 和Ci,0 < Xi < E; 1 ≤ Fi ≤ 100; 1 ≤Ci ≤ 10^6


输出格式:

  • 单个整数:表示购买和运送饲料的最小费用之和


样例输入:

2 5 3
3 1 2
4 1 2
1 1 1


样例输出:

7


样例解释:

  在离家较近的两家商店里各购买一吨饲料,则花在路上的钱是1 + 2 = 3,花在店里的钱是2 + 2 = 4


题解:

  一眼贪心题,但是不会打,只好弄个DP水了过去


参考代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
struct node
{
    int x,f,c;
}a[110];
int cmp(const void *xx,const void *yy)
{
    node n1=*(node *)xx;
    node n2=*(node *)yy;
    if(n1.x>n2.x) return 1;
    if(n1.x<n2.x) return -1;
    return 0;
}
int f[110][110];
int main()
{
    int k,e,n;
    scanf("%d%d%d",&k,&e,&n);
    for(int i=1;i<=n;i++) scanf("%d%d%d",&a[i].x,&a[i].f,&a[i].c);
    qsort(a+1,n,sizeof(node),cmp);
    memset(f,63,sizeof(f));
    for(int i=0;i<=a[1].f;i++) f[1][i]=a[1].c*i;
    for(int i=2;i<=n;i++)
    {
        for(int p=0;p<=k;p++)
        {
            for(int q=0;q<=a[i].f;q++)
            {
                if(p+q>k) break;
                f[i][p+q]=min(f[i][p+q],f[i-1][p]+(a[i].x-a[i-1].x)*p+q*a[i].c);
            }
        }
    }
    printf("%d\n",f[n][k]+(e-a[n].x)*k);
    return 0;
}
posted @ 2017-10-31 07:52  Star_Feel  阅读(285)  评论(0编辑  收藏  举报