链接:点击打开链接
题意:有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; }