zoukankan      html  css  js  c++  java
  • Jzoj4892 最优得分

    给你n道题目,你有t的时间,每个题有一个初始的分数Ai,让后每过1分钟,第i道题目分值减少Bi

    假设你可以做出全部题目,而做一个题i的用时是固定的常数Ci,那么请问你最多能得到多少分

    (好刺激的赛制呢)

    显然是一个dp,但是光dp还不够,我们还要套上贪心才能最优

    考虑当前已经决定做哪几道题目,那么用什么顺序去完成这些题目得分最高?

    我们随便考虑一个顺序X,考虑交换其中两个题目X[j]和X[j+1]

    如果保持不变,那么损失C[x[i]]*B[x[i+1]]分,如果交换,则损失B[x[i]]*C[x[i+1]]分

    比较两者大小,若C[x[i]]*B[x[i+1]]>B[x[i]]*C[x[i+1]]则应该交换两者

    移项可得B[x[i]+1]/C[x[i]+1]>B[x[i]]/C[x[i]]

    所以我们将所有的题目按照B[i]/C[i]从大到小排序

    让后做类似于01背包问题的dp即可

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    struct Q{ int A,B,C; } s[1010];
    int f[3010],n,m;
    inline bool c1(Q a,Q b){ return a.C*b.B>b.C*a.B; }
    int score(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i)
    		scanf("%d%d%d",&s[i].A,&s[i].B,&s[i].C);
    	memset(f,0,3010<<2);
    	sort(s+1,s+1+n,c1);
    	for(int i=1;i<=n;++i)
    		for(int j=m;j>=s[i].C;--j)
    			f[j]=max(f[j],f[j-s[i].C]+s[i].A-(m-j+s[i].C)*s[i].B);
    	printf("%d
    ",f[m]);
    }
    int main(){
    	freopen("score.in","r",stdin);
    	freopen("score.out","w",stdout);
    	int T; for(scanf("%d",&T);T--;score());
    }


  • 相关阅读:
    如何在iOS中使用Block(转)
    blocks 学习(转)
    关于sqlite3 top的查询
    IOS多线程编程
    iOS平台内存常见问题(转)
    关于C中数组的组织存放
    消息推送机制实现与探讨
    IOS单例模式(Singleton)
    assign copy retain
    关于浮动,怪异模式
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/7774814.html
Copyright © 2011-2022 走看看