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

      
    想去写dp 所以就写了dp 这道dp 写的有点失败了,因为我根本 无法实现状态转移,最后看了眼学长的博客。

    求 n个灯分成m组 的最大照明度 毫无疑问的是 设 f[i][j] 表示前i 个灯分成j组能 得到的最大照明。

    可是状态转移的时候 无法转移 纵使我想到了前缀和 但是 唯一缺漏之处是 发现一组的灯里还有不能用的。

    这就很气了,我不知道当前枚举的灯哪个用哪个不用 ,好像写不下去了。

    一组灯中 有不用的灯这不是让搜索么?况且 我还是在一个三重循环中搜索这肯定不行 。

    学长是这样写的 先预处理出 g[i][j] 表示第i个灯到第j个灯的最大照明度。

    对于这一个区间采用搜索寻找出最大的照明度 ,我是真的没想到这是一个01背包问题。

    有容积有价值 为什么不01背包,还是太年轻。又是没想到。。。

    朴素的处理是这样的

    for(int i=1;i<=n;++i)
            for(int j=i;j<=n;++j)
            {
                int s=T*(j-i+1);
                memset(w,0,sizeof(w));
                for(int k=i;k<=j;++k)
                    for(int r=s;r>=a[k];r--)
                        w[r]=max(w[r],w[r-a[k]]+z[k]);
                g[i][j]=w[s];
            }
    View Code

    可是这是接近n^4的复杂度一定GG。

    考虑 怎么搞 我不太会。。

    其实可以这样 对于枚举出的每个i j 灯的个数和体积在增长。

    那么 直接拿出 i~n的全部容量再对每个新出现的灯进行01背包即可 最后只取i~j的容量的价值即可复杂度接近n^3 能A 了。

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<iomanip>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<cctype>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<queue>
    #include<stack>
    #include<deque>
    #include<map>
    #include<vector>
    #include<ctime>
    #define INF 2147483646
    #define ll long long
    #define R register
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
        int x=0,f=1;char ch=getc();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
        return x*f;
    }
    inline void put(int x)
    {
        x<0?putchar('-'),x=-x:0;
        int num=0;char ch[50];
        while(x)ch[++num]=x%10+'0',x/=10;
        num==0?putchar('0'):0;
        while(num)putchar(ch[num--]);
        putchar('
    ');return;
    }
    const int MAXN=200;
    int n,m,T,maxx;
    int a[MAXN],z[MAXN];
    int f[MAXN][MAXN];//f[i][j]表示前i个电灯分成j组能得到的最大照明
    int g[MAXN][MAXN];//g[i][j]表示第i个电灯到第j个电灯为一组的最大照明
    int w[MAXN*50];
    int main()
    {
        //freopen("1.in","r",stdin);
        n=read();m=read();T=read();
        for(int i=1;i<=n;++i)a[i]=read(),z[i]=read();
        for(int i=1;i<=n;++i)
        {    
            int s=T*(n-i+1);
            memset(w,0,sizeof(w));
            for(int j=i;j<=n;++j)
            {
                for(int r=s;r>=a[j];r--)
                    w[r]=max(w[r],w[r-a[j]]+z[j]);
                g[i][j]=w[T*(j-i+1)];
            }
        }
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                for(int k=j-1;k<i;++k)
                    f[i][j]=max(f[i][j],f[k][j-1]+g[k+1][i]);
        put(f[n][m]);
        return 0;
    }
    View Code
  • 相关阅读:
    Java设计模式——自定义Spring框架
    《网络协议从入门到底层原理》笔记(二)MAC地址、IP地址、子网划分、超网
    《网络协议从入门到底层原理》笔记(一)基本概念、通信基础
    Java并发编程——共享模型的线程安全问题
    Java 泛型
    Java并发编程——线程基础知识
    Django实战——面试评估系统
    GIT 撤销上一次merge操作
    解决composer install遇到:Your requirements could not be resolved to an installable set of packages
    yii2乐观锁和悲观锁代码示例
  • 原文地址:https://www.cnblogs.com/chdy/p/10611035.html
Copyright © 2011-2022 走看看