UVA 11400 Lighting System Design DP

                   好吧,理解这道题目的意思确实费了我一番功夫,原来每个category的电源和灯泡之间没有一一对应关系,总之各种方面的无法理解题意。。。。好吧,直接说过程。

                   定义状态dp[i]表示电源电压从低到高的前i个灯泡的最小花费

                   那么从前i个灯泡转移到前i+1个灯泡的过程当中,我们首先注意到一个减少花费的办法是可以用第i+1种灯泡去替换前面i种灯泡中的一些。

                   注意:①要是第i+1种灯泡替换第j种灯泡可以减小花费,那么第j种灯泡一个都不要留,全都换成第i+1种

                               ②替换只发生在区间[k,i]区间中,不可能有替换第k种,第k+2种类似于这样中间有孔的情况。

                                   证明:因为i+1种不能替换第k+1种,因此第k+1比第i+1更好,因此我们可以用第k+1去替换第k种来获得更优,但是我们是计算dp[i+1],之前的都已经是最小值了不可能更小了,因此与这里的更小是矛盾的。

 

                  Tips:我这里用一个map存的电源。。一个结构体存的是灯泡,vol代表voltage电压,val代表value。num数组维护了一个前缀和,快速计算从第j~i有多少个灯泡。ans即为上面的dp。

                  这道题不算100道动态规划,这是我发挥失误了。。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>

using namespace std;

int n,ans[1010],k,num[1010];
map<int,int> vol;
struct Node{
    int vol,val,num;
    bool operator<(const Node&a)const{return vol<a.vol;}
}arr[1010];

int main(){
    while(scanf("%d",&n)&&n){
        for(int i=1;i<=n;++i){
            scanf("%d%d%d%d",&arr[i].vol,&k,&arr[i].val,&arr[i].num);
        if(vol.count(arr[i].vol))
            vol[arr[i].vol]=min(vol[arr[i].vol],k);
        else
            vol[arr[i].vol]=k;
        }
        sort(arr+1,arr+n+1);

        for(int i=1;i<=n;++i){
            num[i]=num[i-1]+arr[i].num;
            ans[i]=num[i]*arr[i].val+vol[arr[i].vol];
            for(int j=1;j<i;++j)
                ans[i]=min(ans[i],ans[j]+(num[i]-num[j])*arr[i].val+vol[arr[i].vol]);
        }

        printf("%d\n",ans[n]);
        vol.clear();
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值