码迷,mamicode.com
首页 > 其他好文 > 详细

Problem 1538 - B - Stones II 贪心+DP

时间:2017-09-14 18:43:48      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:cst   i++   style   for   nes   scanf   bool   printf   namespace   

还是给你石头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

标签:cst   i++   style   for   nes   scanf   bool   printf   namespace   

原文地址:http://www.cnblogs.com/Aragaki/p/7521575.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!