whu 1538 - B - Stones II 01背包

题目链接:

http://acm.whu.edu.cn/land/problem/detail?problem_id=1538

Problem 1538 - B - Stones II


Time Limit: 1000MSMemory Limit: 65536KB
问题描述

Xiaoming took the flight MH370 on March 8, 2014 to China to take the ACM contest in WHU. Unfortunately, when the airplane crossing the ocean, a beam of mystical light suddenly lit up the sky and all the passengers with the airplane were transferred to another desert planet.

When waking up, Xiaoming found himself lying on a planet with many precious stones. He found that:

There are n precious stones lying on the planet, each of them has 2 positive values ai and bi. Each time Xiaoming can take the ith of the stones ,after that, all of the stones’ aj (NOT including the stones Xiaoming has taken) will cut down bi units.

Xiaoming could choose arbitrary number (zero is permitted) of the stones in any order. Thus, he wanted to maximize the sum of all the stones he has been chosen. Please help him.

输入

The input consists of one or more test cases.

First line of each test case consists of one integer n with 1 <= n <= 1000.
Then each of the following n lines contains two values ai and bi.( 1<= ai<=1000, 1<= bi<=1000)
Input is terminated by a value of zero (0) for n.

输出

For each test case, output the maximum of the sum in one line.

样例输入

1
100 100
3
2 1
3 1
4 1
0

样例输出

100
6

题意

有n个物品,你可以任意取若干个,也可以不取,每捡起一个物品i,你将获得a[i]的价值,且所有还没捡起来的物品价值都会-b[i].问最后你能获得的价值。

题解

这题有想到加一维状态表示捡起来的个数,但是被一般的01背包思路定死了!以为会变成O(n^3),但是注意这里的背包没有容量限制,所以你只要O(n^2)的复杂度就能跑完!!!
dp[i][j]表示前i个,拿起j个能够获得的最大收益(其实是要倒过来理解的)。

代码

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#include<sstream>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf

typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;

const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);

//start----------------------------------------------------------------------

const int maxn=1010;

int dp[maxn];

struct Node{
    int a,b;
    bool operator < (const Node& tmp) const {
        return b>tmp.b;
    }
}arr[maxn];

int main() {
    int n;
    while(scf("%d",&n)==1&&n){
        for(int i=1;i<=n;i++) scf("%d%d",&arr[i].a,&arr[i].b);

        sort(arr+1,arr+n+1);

        clr(dp,-1);
        dp[0]=0;

        for(int i=1;i<=n;i++){
            for(int j=n;j>=1;j--){
                if(dp[j-1]>=0){
                    dp[j]=max(dp[j],dp[j-1]+arr[i].a-(j-1)*arr[i].b);
                }
            }
        }

        int ans=0;
        for(int i=1;i<=n;i++) ans=max(ans,dp[i]);

        prf("%d\n",ans);

    }
    return 0;
}

//end-----------------------------------------------------------------------

转载于:https://www.cnblogs.com/fenice/p/5920250.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值