• Problem 1538


    还是给你石头n枚,每一枚石头有两个值a和b,每取一个石头,除了这块石头其余所有的石头的a就都减去这个石头的b,问你取了的石头的a的总和最大可以为多少?

     先按B从大到小排序

    然后DP:

    取的话:dp[i][j]=dp[i-1][j-1]+a[i]-b[i]*(j-1) 注意是j-1

    不取的话:dp[i][j]=dp[i-1][j];

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<sstream>
    #include<cstdlib>
    #include<string>
    #include<string.h>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<stack>
    #include<list>
    #include<queue>
    #include<ctime>
    #include<bitset>
    #define eps 1e-6
    #define INF 0x3f3f3f3f
    #define PI acos(-1.0)
    #define ll __int64
    #define LL long long
    #define lson l,m,(rt<<1)
    #define rson m+1,r,(rt<<1)|1
    #define M 1000000007
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    #define Maxn 1100
    struct Inf
    {
        int a,b;
    }save[Maxn];
    LL dp[Maxn][Maxn];
    int n;
    LL Max(LL a,LL b)
    {
        return a>b?a:b;
    }
    bool cmp(struct Inf a,struct Inf b)
    {
        return a.b>b.b;
    }
    int main()
    {
       //freopen("in.txt","r",stdin);
       //freopen("out.txt","w",stdout);
    
       while(scanf("%d",&n)&&n)
       {
           for(int i=1;i<=n;i++)
               scanf("%lld%lld",&save[i].a,&save[i].b);
           sort(save+1,save+n+1,cmp);
           for(int i=0;i<=n;i++)
                    dp[i][0]=0;
           for(int i=1;i<=n;i++)
           {
               for(int j=1;j<=i;j++)
                    dp[i][j]=max(dp[i-1][j-1]+save[i].a-save[i].b*(j-1),dp[i-1][min(j,i-1)]);
                   //dp[i][j]=Max(dp[i-1][j],dp[i-1][j+1]+save[i].a-save[i].b*j);
           }
           LL ans=0;
           for(int i=1;i<=n;i++)
            ans=max(ans,dp[n][i]);
           printf("%lld
    ",ans);
       }
       return 0;
    }

    另一种状态方程:

    dp[i][j]:表示第i堆后还要选j堆能达到的最大值。

    dp[i][j]=max(dp[i-1][j],dp[i-1][j+1]+a[i]-b[i]*j) ; //要么选要么不选

    //#include<CSpreadSheet.h>
    
    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<sstream>
    #include<cstdlib>
    #include<string>
    #include<string.h>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<stack>
    #include<list>
    #include<queue>
    #include<ctime>
    #include<bitset>
    #define eps 1e-6
    #define INF 0x3f3f3f3f
    #define PI acos(-1.0)
    #define ll __int64
    #define LL long long
    #define lson l,m,(rt<<1)
    #define rson m+1,r,(rt<<1)|1
    #define M 1000000007
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    
    #define Maxn 1100
    
    struct Inf
    {
        int a,b;
    }save[Maxn];
    LL dp[Maxn][Maxn];
    int n;
    
    
    LL Max(LL a,LL b)
    {
        return a>b?a:b;
    }
    
    bool cmp(struct Inf a,struct Inf b)
    {
        return a.b<b.b;
    }
    
    int main()
    {
       //freopen("in.txt","r",stdin);
       //freopen("out.txt","w",stdout);
    
       while(scanf("%d",&n)&&n)
       {
           for(int i=1;i<=n;i++)
               scanf("%lld%lld",&save[i].a,&save[i].b);
           memset(dp,-INF,sizeof(dp)); //无效状态
           //printf("%d
    ",dp[1][1]);
           sort(save+1,save+n+1,cmp);  //顺序 肯定对b从小到大比较优
           for(int i=0;i<=n;i++)
                dp[0][i]=0;
    
           for(int i=1;i<=n;i++)
           {
               for(int j=0;j<=n;j++)
                   dp[i][j]=Max(dp[i-1][j],dp[i-1][j+1]+save[i].a-save[i].b*j);
    
           }
           printf("%lld
    ",dp[n][0]);
    
       }
       return 0;
    }
  • 相关阅读:
    HDU5195 线段树+拓扑
    Codeforces Round #328 (Div. 2)D. Super M 虚树直径
    HDU5489 LIS变形
    BZOJ 1787: [Ahoi2008]Meet 紧急集合 LCA
    Codeforces Round #330 (Div. 2)B. Pasha and Phone 容斥
    Codeforces Round #330 (Div. 2) D. Max and Bike 二分
    Codeforces Round #277 (Div. 2) E. LIS of Sequence DP
    Codeforces Round #277 (Div. 2) D. Valid Sets DP
    内存对齐
    mui列表跳转到详情页优化方案
  • 原文地址:https://www.cnblogs.com/Aragaki/p/7521575.html
Copyright © 2020-2023  润新知