Problem: The World Final II(NEUOJ1175)排序+动态规划

The World Final is coming! Next week our seniors, Brother Head, Little Bin and God Tan will fight for the glory of NEU.

The rule of the world final is as follow:

1. if two teams have the different solved problems, then the one who have more solved problems will get higher rank;

2. if two teams have the same solved problems, then the one who have less penalty, which equals 0 initially, will get higher rank;

3. if one team get first AC of a problem, then their penalty will add a number which equal the time they first AC it, and if they tried failed k times to solve it before they AC it, then they will get more k*20 penalty;

4. the total time of the world final is 300 (including 300), and begin at time 0.

Now our seniors know how long will they solve each problem and how many times will they failed before they AC it. They wanna take a best strategy to get higher rank.

Input
There are T groups of test data. The first line contains one positive integer T (1<=T<=100).

For each test data : the first line contains an integer n(1<=n<=15), which is the number of total problems. Then follows n line, each line contains two numbers: ti and ki,(1<=ti<=300, 0<=ki<=1000) which means how long will they AC it (not the time they AC it), and how many times they failed before they AC it.

【hint】:

In the second sample input, they solve the 2nd problem firstly, then solve the 1st problem, solve they solved 2 problems in total, and penalty=(2+100*20)+(292+2*20)=2334.

Output
For each case, output one line contains two numbers separated by a space: the most number of problems they can solve, and the less penalty in that case.

Sample Input
2 2 290 2 299 1 3 290 2 2 100 299 1
Sample Output
1 319 2 2334
Source
morejarphone
Hint
No Hint!
Submit
具体题目就是这样,一共有n道题,每道题有特定的时间和固定的失败次数(这居然也能知道!!),规则acm的同学应该都能很清楚了~比赛一共300分钟,每做出一道题ac数加一,所用时间增加量为当前的时间数,每失败一次增加20分钟的罚时。(比如在一小时的时候做出一道题,用的时间就加上(60+20*失败次数))最后要看总的过题数来排名,过题数相同的所用时间越少名次越靠前。最后要求输出在规定时间内的最好情况(即过题数(最多)和所用时间(最少))。

我用的方法是01背包dp求解,背包容量是300分钟,对于一道题,更新条件是可以增加过题数或者过题数不变但是时间减小。这里还有一个问题,在使用背包前要对数据排一下序,因为如果最后通过的题目固定,那么想要让时间最少,就要把用时较少的题目排在前面,因为失败次数*20是固定罚时,和过题时间没有关系。所以对于两道用时不同的题目,一定要先做用时少的那道来保证时间最小(表示写排序的部分比较弱,偷偷用sort排序。。。不过要重载一下小于号,这个应该都会ba。。,除此以外还可以使用排序函数然后在sort里添加第三参数来执行)最后遍历一下数组找到最大的过题数(优先),和最少的使用时间,最后输出就好啦~

AC代码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>

using namespace std;

class ti
{
public:
int ft,ts;
bool operator <(const ti &b)const//重载操作符
{
if(ft<b.ft)
return true;
else
return false;
}
};

ti dp[50];

int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
int num[310]={0},time[310]={0};
int x=0,y=0x3f3f3f3f;//0x3f3f3f3f近似极大值
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&dp[i].ft,&dp[i].ts);
sort(dp+1,dp+n+1);//注意别把dp【0】排序
for(int i=1;i<=n;i++)
for(int j=300;j>=dp[i].ft;j--)
{
if(time[j]==0)
{
num[j]++;
time[j]=dp[i].ft+20*dp[i].ts;
}
else if(num[j]-num[j-dp[i].ft]==1)//过题数部不变但是时间减少的情况
{
if(time[j]>time[j-dp[i].ft]+20*dp[i].ts+j)
{
num[j]=num[j-dp[i].ft]+1;
time[j]=time[j-dp[i].ft]+20*dp[i].ts+j;
}
}
else if(num[j]-num[j-dp[i].ft]==0)//可增加过题数的情况
{
num[j]=num[j-dp[i].ft]+1;
time[j]=time[j-dp[i].ft]+20*dp[i].ts+j;
}
// printf("%d :num%d=%d time%d=%d\n",i,j,num[j],j,time[j]);
if(num[j]==x)////这一段判断时要注意先判断过题数的变化,过题数量减少的,最小时间不要变,wa了一次。。。。
y=min(y,time[j]);
else if(num[j]>x)
{
x=num[j];
y=time[j];
}
}
printf("%d %d\n",x,y);
}
return 0;
}

时间: 2024-10-02 16:31:52

Problem: The World Final II(NEUOJ1175)排序+动态规划的相关文章

FZU Problem 2171 防守阵地 II (线段树,区间更新)

 Problem 2171 防守阵地 II Accept: 143    Submit: 565Time Limit: 3000 mSec    Memory Limit : 32768 KB  Problem Description 部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵的能力之和.随着时间的推移,指挥部将下达Q个指令来替换M个进行防守的士兵们,每个参加完防守

FZU Problem 2171 防守阵地 II (裸线段树 懒惰标记)

 Problem 2171 防守阵地 II Accept: 259    Submit: 987 Time Limit: 3000 mSec    Memory Limit : 32768 KB Problem Description 部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵的能力之和.随着时间的推移,指挥部将下达Q个指令来替换M个进行防守的士兵们,每个参加完防守

leetcode——Remove Duplicates from Sorted List II 删除排序字符串中重复字符(AC)

Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. For example, Given 1->2->3->3->4->4->5, return 1->2->5. Given 1->1->1->2->3, return 2->3

【LeetCode-面试算法经典-Java实现】【082-Remove Duplicates from Sorted List II(排序链表中删除重复元素II)】

[082-Remove Duplicates from Sorted List II(排序链表中删除重复元素II)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. For example, Given 1->2->

Problem Linked List Cycle II

Problem Description: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follow up:Can you solve it without using extra space?  Solution: 1 public ListNode detectCycle(ListNode head) { 2 if (head == null) r

Problem Pascal&#39;s Triangle II

Problem Description: Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3,Return [1,3,3,1]. Note:Could you optimize your algorithm to use only O(k) extra space? Solution: 1 public List<Integer> getRow(int rowIndex)

lintcode 容易题:Merge Sorted Array II 合并排序数组 II

题目: 合并排序数组 II 合并两个排序的整数数组A和B变成一个新的数组. 样例 给出A = [1, 2, 3, empty, empty] B = [4,5] 合并之后A将变成[1,2,3,4,5] 注意 你可以假设A具有足够的空间(A数组的大小大于或等于m+n)去添加B中的元素. 解题: 这里给的是两个数组,上题给的是ArrayList格式,比较好处理,重新定义一个长度m+n的数组,太无节操,其他方法一时想不起来 官方解题,方法很技巧,可以倒着排序,这样就很简单了 Java程序: class

URAL 1100. Final Standings (排序)

1100. Final Standings Time limit: 1.0 second Memory limit: 16 MB Old contest software uses bubble sort for generating final standings. But now, there are too many teams and that software works too slow. You are asked to write a program, which generat

[JMM]__JMM中引用类型final域重排序规则

对于final域为引用类型的情况: 1,在构造函数内,对于一个final域为引用类型及对其引用的对象的成员变量的写入,与随后在构造函数外将被构造的对象赋值给另一引用变量,这2个操作不能被重排序. 如下图详解: