Problem 1538 - B - Stones II 贪心+DP

Posted Aragaki

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Problem 1538 - B - Stones II 贪心+DP相关的知识,希望对你有一定的参考价值。

还是给你石头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\n",ans);
   }
   return 0;
}

 

以上是关于Problem 1538 - B - Stones II 贪心+DP的主要内容,如果未能解决你的问题,请参考以下文章

ZZNUOJ_用Java编写程序实现1538:都是素数么(附源码)

bzoj1538 [NWERC2017]High Score

CodeForces - 1538G Gift Set(二分)

CF 1110 E. Magic Stones

Codeforces Round #593 (Div. 2) A. Stones

Codeforces Round #725 (Div. 3)Codeforces-1538