链接:点击打开链接
题意:有n堆石头,每拿一堆,所有石头的a值都减去自身的b,求能够到拿的a的和的最大值
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
struct node{
long long a,b,v;
friend bool operator<(node x,node y){
return x.v>y.v;
}
}s[1005];
int main(){ //因为第i次取第j个物品,所获得的价值
long long n,i,j,ans,sum; //为s[j].a-i*s[j].b,因此第i次取得时
while(scanf("%lld",&n)!=EOF&&n){ //候取s[j].a-i*s[j].b值最大的i个即可
for(i=0;i<n;i++)
scanf("%lld%lld",&s[i].a,&s[i].b);
ans=0;
for(i=1;i<=n;i++){
for(j=0;j<n;j++)
s[j].v=s[j].a-i*s[j].b;
sort(s,s+n);
sum=0;
for(j=1;j<=i;j++)
sum+=s[j-1].v;
ans=max(ans,sum); //比较哪一次取出最大值
}
printf("%lld\n",ans);
}
return 0;
}
链接:点击打开链接
题意:有n堆石头,每拿一堆,没有被拿的石头堆的a都要减去自身的b,求能够拿到的a的和的最大值
代码:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
struct node{
int a,b;
friend bool operator <(node x,node y){
return x.b>y.b; //让b值大的先被抽取
}
}s[1005];
int dp[1005][1005];
int main(){ //因为这个题与上一个题的区别
int n,i,j,ans; //在于是剩下的物品减去自身的b[i]
while(scanf("%d",&n)!=EOF&&n){ //所以无法直接确定每次选取哪一个
ans=0; //所以需要用动态规划
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
scanf("%d%d",&s[i].a,&s[i].b);
sort(s+1,s+n+1); //因为第几次被抽取会影响自身的价值,
for(i=1;i<=n;i++) //因此需要排序
for(j=i;j>=1;j--) //dp[i][j]代表前i次中抽取j个
dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+s[i].a-s[i].b*(j-1));
for(i=1;i<=n;i++)
ans=max(ans,dp[n][i]);
printf("%d\n",ans);
}
return 0;
}