题意:给出n种灯泡,分别给出它们的电压v,电源费用k,每个灯泡的费用c,和所需灯泡的数量l,问最优方案的费用
看的紫书= =
首先是dp[i]为灯泡1到i的最小费用,
dp[i]=min(dp[i],dp[j]+(s[i]-s[j])*a[i].c+a[i].k);
表示前j个先用最优方案买,然后第j个到第i个都用i号电源(唉= =想这里想了好久的说,不过后来发现紫书上是这样写的:同一种灯泡可以使用一个电源,所以这里从第j个到第i个灯泡都使用的是i号电源)
又因为:题目中说可以把一些灯泡换成电压更高的另一种灯泡来节省电源的钱(所以需要对电源进行升序排列)
这道题目还是没有写对初始化
自己错误的写成了: dp[i]=a[i].k+a[i].l*a[i].c;
这样就只算了i这一种灯泡的(没有计算到电压比i这种小的也可以用i这种电源的情况,所以不对)
应该这样:
dp[i]=a[i].k+s[i].*a[i].c(其中s[i]为前i种灯泡的总数量)
#include<iostream>
#include<cstdio>
#include<cstring>
#include <cmath>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<algorithm>
#define mod=1e9+7;
using namespace std; typedef long long LL;
const int maxn=;
int dp[maxn],s[maxn]; struct node{
int v,k,c,l;
} a[maxn]; int cmp(node n1,node n2){
return n1.v<n2.v;
} int main(){
int n,i,j;
while(scanf("%d",&n)!=EOF&&n){ for(i=;i<=n;i++){
scanf("%d %d %d %d",&a[i].v,&a[i].k,&a[i].c,&a[i].l);
} sort(a+,a+n+,cmp); s[]=;
for(i=;i<=n;i++) s[i]=s[i-]+a[i].l; dp[]=;
for(i=;i<=n;i++){
dp[i]=a[i].k+s[i]*a[i].c;
for(j=;j<=i;j++){
dp[i]=min(dp[i],dp[j]+(s[i]-s[j])*a[i].c+a[i].k);
// printf("dp[%d]=%d\n",i,dp[i]);
}
}
printf("%d\n",dp[n]);
}
return ;
}