题目链接:
http://acm.whu.edu.cn/land/problem/detail?problem_id=1538
Problem 1538 - B - Stones II
Memory Limit: 65536KB
输入
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(n3),但是注意**这里的背包没有容量限制**,所以你只要O(n2)的复杂度就能跑完!!!
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
",ans);
}
return 0;
}
//end-----------------------------------------------------------------------