zoukankan      html  css  js  c++  java
  • 关灯问题

    看lzx的题解才写出来,lzx太神辣

    原题:

    在四川省绵阳中学的毓才路上,新建了若干漂亮的路灯,这给同学们晚上的出行带来很大的方便。但是,问题随之出现了。
    一天晚上,我们信息学竞赛班的 SFJ 同学正往校门外走,忽然眼前一片漆黑,于是直 接把眼镜都摔掉了,再也找不到。后来 SFJ 同学从学校管理处了解到昨晚路灯突然熄灭是 因为电路不堪重负,导致空气开关跳闸。
    善于思考的 SFJ 同学考虑将路灯进行改建,以避免再次出现类似的问题。
    SFJ 同学仔细了解每盏路灯的耗电量 a[i]与照明度 z[i],已知共有 N 盏电灯,并且每盏电灯都可能有不同的耗电量与照明度,现在的问题是要把这 N 盏电灯分为 M 组,新分出的每组灯的耗电量(即是该组所有打开电灯的耗电量之和)不能超过该组的电灯数目的 T倍,在满足这样的前提下使得照明度尽可能的大,最后算出 M 组的最大照明度的和。由于每组耗电量的限制,该组中的某些电灯可能不被使用,但是仍然应该算作该组灯的数目。特别注意的是电灯按顺序给出,只能把相邻的几盏灯分在一组。 由于计算较为复杂,SFJ 同学经过反复的计算仍然不能确定结果,现在就请你为他编写
    一个程序来解决这个问题。

    2<=N<=160,1<=M<=50,1<=T,a[i],z[i]<=50

    n^4很容易想

    现在关键是如何优化到n^3

    首先先确定一下思路,思路不一样后面可能会不太好搞

    背包求f[i][j]表示从i到j最优值,然后g[i][j]表示直到i分了j组最优值,g[i][j]=max{g[j-1][k-1]+f[j][i]}

    (感觉这个思路对我不太友好啊,我不怎么习惯这种思路

    然后呢其实求f[i][j]的背包是可以重复使用的,只要最后结算到f[i][j]的时候使用的是j的上限即可

    这个就需要知道背包如果不限制必须装满的话f[容量]就是最大值,因为不必从0开始装(我在做这道题之前还真不知道……
    似乎可以用有理有据的底层优化n^4卡过?

    可以尝试一下

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<vector>
     7 using namespace std;
     8 int rd(){int z=0,mk=1;  char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')mk=-1;  ch=getchar();}
    10     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    11     return z*mk;
    12 }
    13 int n,m,c,a[210],b[210];
    14 int f[8100],g[210][210],h[210][210];
    15 int main(){//freopen("ddd.in","r",stdin);
    16     cin>>n>>m>>c;
    17     for(int i=1;i<=n;++i)  a[i]=rd(),b[i]=rd();
    18     for(int i=1;i<=n;++i){
    19         memset(f,0,sizeof(f));
    20         int w=(n-i+1)*c;
    21         for(int j=i;j<=n;++j){
    22             for(int k=w;k>=a[j];--k)
    23                 f[k]=max(f[k],f[k-a[j]]+b[j]);
    24             g[i][j]=f[(j-i+1)*c];
    25         }
    26     }
    27     for(int i=1;i<=n;++i)
    28         for(int k=1;k<=m && k<=i;++k)
    29             for(int j=k;j<=i;++j)
    30                 h[i][k]=max(h[i][k],h[j-1][k-1]+g[j][i]);
    31     cout<<h[n][m]<<endl;
    32     return 0;
    33 }
    View Code
  • 相关阅读:
    .Net Discovery系列之深入理解平台机制与性“.NET技术”能影响(下) 狼人:
    MEF——.NE“.NET技术”T中值得体验的精妙设计 狼人:
    .NET中的异步编程 IO完“.NET技术”成端口以及FileStream.BeginRead 狼人:
    Entity Fr“.NET技术”amework 4.1 Code First 学习之路(二) 狼人:
    也玩MVC3.0 Razor自定义视图引擎“.NET技术”来修改默认的Views目录结构 狼人:
    引用类型赋值“.NET技术”为null与加速垃圾回收 狼人:
    在C#“.NET技术”中选择正确的集合进行编码 狼人:
    “.NET技术”Ajax和WEB服务数据格式:自定义返回格式 狼人:
    C#权限管理和设计浅“.NET技术”谈 狼人:
    带你走进缓“.NET技术”存世界 狼人:
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6430961.html
Copyright © 2011-2022 走看看