zoukankan      html  css  js  c++  java
  • bzoj4247挂饰——DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4247

    就是01背包;

    把挂钩数限制在n以内,因为不需要更多,而这会带来一些问题,就是有很多挂钩的物品按原来的方法就不能挂了;

    但其实我们已经忽略了过多的挂钩,所以不能严格按实际的挂钩数量来遍历第二维;

    <<也就是说此时的状态表示至少剩余多少个挂钩!>>

    注意那个max,表示抽象意义,令所有小于此物品挂钩数的状态最差也不差于挂一个此物品(于是用挂一个此物品替代),这样得到的答案能保证正确,可以看做是忽略多余的挂钩;

    (也就是负数也可以挂,顺便令此时取到最优值,也就是只剩1个钩时的状态<限制最少>);

    由于只挂一个此物品,也就是只需要一个钩去挂,因此用挂钩数剩1的状态转移,而那个剩1也已经是它最好的状态。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int const MAXN=2005,inf=2e9;
    int n,f[MAXN][MAXN],ans;
    struct N{
        int a,b;
    }p[MAXN];
    bool cmp(N x,N y){return x.a>y.a;}
    int main()
    {
        memset(f,-210000000,sizeof f);//
        f[0][1]=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d%d",&p[i].a,&p[i].b);
        sort(p+1,p+n+1,cmp);
        for(int i=1;i<=n;i++)
            for(int j=0;j<=n;j++)
                f[i][j]=max(f[i-1][j],f[i-1][max(j-p[i].a,0)+1]+p[i].b);//!
        ans=-inf;
        for(int j=0;j<=n;j++)
            ans=max(ans,f[n][j]);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    HDU 4296 Buildings(贪心)
    HDU 4288 Coder(线段树)
    hdu 5073 Galaxy
    ZOJ 3905 Cake(贪心+dp)
    ZOJ 3903 Ant(公式推导)
    除法求逆元(扩展欧几里德和费马小定理)
    HDU 4442 Physical Examination(关于贪心排序)
    ACM vim配置
    2015 南阳ccpc The Battle of Chibi (uestc 1217)
    次小生成树(入门)
  • 原文地址:https://www.cnblogs.com/Zinn/p/8724154.html
Copyright © 2011-2022 走看看