poj 2976 Abandon des tests (programmation fractionnaire 0/1)

Limite de temps : 1000 MS Limite de mémoire :  65 536 Ko
Total des soumissions :  31 958 Accepté :  10375

Description

Dans un certain cours, vous passez  n  tests. Si vous obtenez  ai  des  questions bi  correctes au test  i , votre moyenne cumulée est définie comme étant

.

Compte tenu de vos résultats aux tests et d'un entier positif  k , déterminez jusqu'où vous pouvez atteindre votre moyenne cumulée si vous êtes autorisé à laisser tomber l'un  de  vos résultats aux tests.

Supposons que vous passiez 3 tests avec des scores de 5/5, 0/1 et 2/6. Sans abandonner aucun test, votre moyenne cumulée est de 

. Cependant, si vous abandonnez le troisième test, votre moyenne cumulée devient .

Saisir

Le fichier de test d'entrée contiendra plusieurs cas de test, chacun contenant exactement trois lignes. La première ligne contient deux entiers, 1 ≤  n  ≤ 1000 et 0 ≤  k  <  n . La deuxième ligne contient  n  entiers indiquant  ai  pour tout  i . La troisième ligne contient  n  entiers positifs indiquant  bi  pour tout  i . Il est garanti que 0 ≤  ai  ≤  bi  ≤ 1 000 000 000. La fin de fichier est marquée par un scénario de test avec  n  =  k  = 0 et ne doit pas être traitée.

Sortir

Pour chaque cas de test, écrivez une seule ligne avec la moyenne cumulée la plus élevée possible après avoir supprimé  k  des résultats de test donnés. La moyenne doit être arrondie à l’entier le plus proche.

Exemple d'entrée

3 1 
5 0 2 
5 1 
6 
4 2 1 2 7 9 
5 6 7 9 
0 0

Exemple de sortie

83 
100

Indice

Pour éviter les ambiguïtés dues aux erreurs d'arrondi, les tests de jugement ont été construits de manière à ce que toutes les réponses soient éloignées d'au moins 0,001 d'une limite de décision (c'est-à-dire que vous pouvez supposer que la moyenne n'est jamais de 83,4997).

Idées :

sur le sujet

 Pour simplifier, essayez de trouver le x inférieur à .

Le point final gauche est 0 et le point final droit est la somme cumulée de ai. Il s'agit d'une recherche binaire efficace.

Lors de la réalisation d’une dichotomie, il est également nécessaire de déterminer si elle est monotone.

#include<stdio.h>
#include<algorithm>
#include<iostream>
using namespace std;
struct Pair {
	int a, b;
	double y;
}p[1005];
bool cmp(Pair a, Pair b) {
	return a.y > b.y; // 从大到小
}
int n, k;
bool check(double x) {
	for (int i = 0; i < n; i++) {
		p[i].y = p[i].a * 1.0 - x * p[i].b; // y = a - x*b  在x轴小点的值
	}
	sort(p, p + n, cmp);
	double f = 0;
	for (int i = 0; i < k; i++) f += p[i].y;
	return f < 0;
}
int main() {
	while (cin >> n >> k, n + k) {
		k = n - k; // 选出 k 对
		for (int i = 0; i < n; i++) cin >> p[i].a;
		for (int i = 0; i < n; i++) cin >> p[i].b;
		double L = 0, R = 0;
		for (int i = 0; i < n; i++)	R += p[i].a;
		for (int i = 0; i < 50; i++) {
			double mid = L + (R - L) / 2;
			if (check(mid)) R = mid;
			else L = mid;
		}
		printf("%d\n", (int)(100 * (L + 0.005)));
	}
	return 0;
}

Je suppose que tu aimes

Origine blog.csdn.net/zhi6fui/article/details/128616271
conseillé
Classement