uva 11400 Lighting System Design

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2395

题目解法:由于灯具只能由电压低的转向电压高的,则可以得知这个转换是有序的。友n<1000即n^2的算法可以过。由此我们可以看看能不能推出他的转移方程。我们可以先将灯具按电压由低到高排序,然后按照这个以d[i]=min(d[i],d[j]+(s[i]-s[j])*p[i].c+p[i].k)更新即可。d[i]表示以i种结尾的最小值。s[i]是前i种的灯具总数。

AC:#include <algorithm>
#include <string>
#include <iostream>
#include <string.h>
#include<stdio.h>
#include<cmath>
#include<vector>
using namespace std;
#define ll  unsigned long long int
const int maxn=1000+10;
const int inf=100000000;
struct lamp
{
    int v,c,k,l;
} p[maxn];
int s[maxn],d[maxn];
bool cmp(lamp a,lamp b)
{
    return a.v<b.v;
}
int main()
{
    int n;
    while(scanf("%d",&n)==1&&n)
    {
        for(int i=1;i<=n;i++)
        {
            d[i]=inf;
        }
        memset(s,0,sizeof s);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d%d",&p[i].v,&p[i].k,&p[i].c,&p[i].l);
        }
        sort(p+1,p+n+1,cmp);
        for(int i=0;i<=n;i++)
        {
            if(i==0){  s[i]=0; }
            s[i]=s[i-1]+p[i].l;
        }
        for(int i=0;i<=n;i++)
        {
            if(i==0) d[i]=0;
            else for(int j=0;j<i;j++)
            {
               d[i]=min(d[i],d[j]+(s[i]-s[j])*p[i].c+p[i].k);
            }
        }
        printf("%d\n",d[n]);
    }
}

你可能感兴趣的:(dp,ACM,uva)