1. 程式人生 > >uva11400(對dp的進一步思考)

uva11400(對dp的進一步思考)

思路:這次比之前想到的會多一些,不過還不夠,具體過程在程式碼中

程式碼如下:

/*
條件:高v的燈可以替換低v的燈 
思路1:dp[i]表示(1->i)號燈泡經過替換後得到的mincost,dp[i+1]為min(i替換成i+1...i+n)+dp[i];錯誤! 
因為該子結構不具有子問題獨立性:之前的燈泡替換成之後的燈泡,那麼對之後的燈泡能否替換就將產生影響
思路2:(對上面的思路進行限制)
只用i號燈泡替換之前的燈泡,並且設定j,[1,j]號燈泡用最優方案,[j+1,i]換成i號燈泡
最優子結構是:前i種燈泡的最小花費
子問題是: min([1,j]號燈泡用最優方案,[j+1,i]換成i號燈泡;(0<j<i))
假設子問題不包含最優解,即[1,j]號燈泡的最優方案非最優,(因為j歷遍了每種情況)矛盾;
*/
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 1010 
int dp[maxn];
int n;
struct node
{
	int v,k,c,l;
}cate[maxn];
int s[maxn];//代表前i種燈的需求和 
bool cmp(node a,node b)
{
	return a.v<b.v;
}
int main()
{
	while(scanf("%d",&n),n)
	{
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d%d%d",&cate[i].v,&cate[i].k,&cate[i].c,&cate[i].l);
			
		}
		sort(cate+1,cate+n+1,cmp);
		for(int i=1;i<=n;i++)
		{
			s[i]=s[i-1]+cate[i].l;
		}
		for(int i=1;i<=n;i++)
		{
			dp[i]=s[i]*cate[i].c+cate[i].k;//全用i號
			for(int j=1;j<=i;j++)
			{
				dp[i]=min(dp[i],dp[j]+(s[i]-s[j])*cate[i].c+cate[i].k);
			} 
			
		}
		printf("%d\n",dp[n]);
	}
	return 0;
}