[PYTHON] Journal de dévotion professionnel compétitif 20e au 22e jour (7/14 au 7/16)

<! - Modèle de dévotion professionnelle compétitive->

Impressions

Récemment, j'ai l'impression qu'il existe de nombreuses méthodes gourmandes. Je ne suis pas doué pour ça, alors je veux m'y habituer. Ce serait formidable si nous pouvions voir le taux augmenter bientôt ...

20ème jour

ABC141-E Who Says a Pun?

Temps pris

50 minutes Je pensais que cela passerait si je poussais $ O (N ^ 3) $, mais je ne pouvais pas le faire et je l'ai fondu pendant 20 minutes supplémentaires.

Considération

Pour penser à une chaîne de caractères qui apparaît plus d'une fois, il suffit qu'une certaine chaîne de caractères apparaisse au moins deux fois, alors mettez ces deux chaînes de caractères dans $ s_1 $, $ s_2 $ et ci-dessous.

Tout d'abord, je doute de DP car il s'agit d'une sous-chaîne. Cependant, je me suis perdu en essayant de traiter les deux choses que les chaînes de caractères ne se chevauchent pas ** et ** pensent dans la même chaîne de caractères ** en même temps, et de les diviser en avant le caractère $ i $ et après le caractère $ i + 1 $ J'ai pensé, mais c'était une mauvaise décision.

Au cours de mon examen, je me suis concentré sur la ** continuité ** et j'ai pensé qu'elle pouvait être résolue par une méthode simple similaire à la méthode de l'échelle **. Autrement dit, le premier caractère de $ s_1 $ est le caractère $ i $ ($ N $ street), et le premier caractère de $ s_2 $ est le caractère $ j (i + 1 \ leqq j \ leqq N) $ ($ Ni $). Considérez la chaîne la plus longue dans laquelle $ s_1 $ et $ s_2 $ correspondent (jusqu'à $ N $). Dans ce cas, ce sera $ O (N ^ 3) $, donc ce ne sera pas à temps. (Il n'est pas bon que la discussion ait duré jusqu'à présent près de 30 minutes.)

Par conséquent, afin de calculer efficacement cette méthode, ** examinez s'il y a une enquête inutile **. Ensuite, vous pouvez voir que ** la même partie est calculée à plusieurs reprises dans la partie qui détermine si les parties continues correspondent **. Par conséquent, ** vous pouvez améliorer l'efficacité en calculant d'abord la partie arrière **, afin de pouvoir préparer la matrice suivante et effectuer DP.

$ dp [i] [j]: = $ (Le plus long préfixe commun lorsque $ s_1 $ commence par le caractère $ i $ et $ s_2 $ commence par le caractère $ j $, mais lorsque $ i = 0 $ Et $ s_1 $ et $ s_2 $ ne se chevauchent pas, y compris lorsque $ j = 0 $)

Ici, la classification des cas de la transition DP lors du calcul à partir de la dernière partie est la suivante, et la valeur maximale en dp est la réponse en implémentant cela.

(1) Quand ($ i $ caractère de $ s $) $ = $ ($ j $ caractère de $ s $)   dp[i][j]=dp[i+1][j+1]+1

(2) Quand ($ i $ caractère de $ s $) $ \ neq $ ($ j $ caractère de $ s $)   dp[i][j]=0

(✳︎) $ dp [i] [j] $ ne peut être que $ j-i $ au plus S'il dépasse cela, $ dp [i] [j] = 0 $ peut être défini.

(1), (2), (✳︎) peuvent être représentés respectivement, mais ils sont omis ici.

Postscript

・ Quel est le préfixe commun le plus long? Il s'agit du plus long préfixe commun des chaînes s et t. Le préfixe commun le plus long lorsque s = ABCBC, t = ABD est AB et le préfixe commun le plus long lorsque s = ABC, t = BCD est une chaîne de caractères vide.

・ Connaissance obtenue cette fois Le problème du modèle de réduction de $ N $ d'environ $ O (N ^ 3) $ → $ O (N ^ 2) $ est ** Si vous faites attention à savoir s'il y a un endroit où vous calculez de manière répétée et inutile Je peux réduire le montant **, j'ai donc décidé de le commander. En outre, il semble que ce problème puisse être résolu de différentes manières en utilisant divers algorithmes de chaîne.

<détails>

Code Python </ summary>

abc141.py


n=int(input())
s=input()
dp=[[0]*(n+1) for i in range(n+1)]
for i in range(n-1,-1,-1):
    for j in range(n-1,i,-1):
        if s[j]==s[i] and dp[i+1][j+1]+1<=j-i:
            dp[i][j]=dp[i+1][j+1]+1
ans=0
for i in range(n):
    for j in range(n):
        ans=max(ans,dp[i][j])
print(ans)

ABC091-C 2D Plane 2N Points

Temps pris

J'ai réfléchi environ 30 minutes et j'ai abandonné.

Cause d'erreur

J'essayais de le résoudre avec une méthode gourmande qui ne pouvait être clairement prouvée. Je n'ai pas pu essayer une solution typique. (Cela ne devrait pas être si difficile ...)

Considération

Premièrement, puisqu'il y a deux ensembles de points bleus et de points rouges, nous considérons ici les points rouges optimaux ** lorsque les points bleus sont fixes ($ \ car $ fixe les points rouges). Le choix du meilleur point bleu pour le moment est essentiellement le même.)

Ici, étant donné que seuls quelques points rouges peuvent être sélectionnés pour les points bleus avec une petite coordonnée x, il est préférable de sélectionner d'abord ces points ($ \ car $ ** coordonnée x et y en même temps. Compte tenu des coordonnées, c'est difficile, donc un seul ** sera considéré en premier.) Par conséquent, nous allons sélectionner les points bleus dans l'ordre de celui avec la plus petite coordonnée x, et sélectionner le point rouge le plus approprié pour chacun ($ \ car $ ** Dans la méthode gourmande, l'ordre de sélection est important !! **).

Sous ce qui précède, le point optimal est ** le point avec la plus grande coordonnée y (quelle que soit la coordonnée x) parmi les points rouges sélectionnables **. En effet, les coordonnées x des points rouges qui peuvent être sélectionnés maintenant sont toujours plus petites que les points bleus qui sont sélectionnés après cela, car les points bleus avec les coordonnées x les plus petites sont sélectionnés dans l'ordre et la coordonnée y doit être aussi petite que possible.

À partir de la considération ci-dessus, en enregistrant le point rouge dans l'ordre décroissant de la coordonnée y et le point bleu dans l'ordre croissant de la coordonnée x, il peut être implémenté en tournant la boucle for seulement deux fois, et $ O (N ^ 2) C'est une solution à $ (il peut être déposé dans $ O (N \ log {N}) $, mais c'est un peu lourd à mettre en œuvre).

(Il semble que nous puissions réduire le problème de la correspondance maximale des graphiques en deux parties, donc j'espère que nous pourrons y remédier un jour.)

<détails>

Code Python </ summary>

abc91c.py


n=int(input())
red=sorted([list(map(int,input().split())) for i in range(n)],key=lambda x:x[1],reverse=True)
blue=sorted([list(map(int,input().split())) for i in range(n)])
ans=0
for bx,by in blue:
    for rx,ry in red:
        if rx<bx and ry<by:
            ans+=1
            red.remove([rx,ry])
            break
print(ans)

21e jour

Résolu Acing Programming Contest 2020-E Camel Train. Cet article explique ・

22ème jour

ABC144-E Gluttony

Temps pris

27 minutes

Considération

Premièrement, la combinaison qui minimise la valeur maximale du produit est celle dans laquelle les coûts de digestion sont classés par ordre croissant et la difficulté à manger est classée par ordre décroissant. Il est bon de montrer que ** vous n'obtiendrez aucun avantage lorsque vous réorganiserez la combinaison optimale ** (ou vous obtiendrez un avantage lorsque vous réorganiserez la combinaison non optimale **) (pour plus d'informations, [ARMERIA] Article](voir https://betrue12.hateblo.jp/entry/2019/10/30/011052). Voici une brève explication.

IMG_0483.JPG

(Ci-après, dans cette combinaison, le $ i $ ème coût de digestion à partir du front est représenté par $ a [i] $, et le $ i $ ème à partir du front est représenté par $ f [i] $.)

J'ai fait cette combinaison dans l'état initial et j'ai essayé de simuler ** $ K $ fois ** en utilisant priority_queue à partir de là **, mais $ K $ est aussi grand que $ 10 ^ {18} $, donc c'est dans le temps. ne pas.

Maintenant, quand je pensais à réduire $ K $ en une seule fois au lieu d'un par un, j'ai supposé que ** chaque produit pouvait être inférieur ou égal à une certaine valeur de $ x $ **. Alors, si la combinaison de $ (f [i], a [i]) $ est $ a [i] \ rightarrow [\ frac {x} {f [i]}] $, le produit sera le nombre minimum de formations. Peut être inférieur à $ x $ ($ a [i] \ leqq [\ frac {x} {f [i]}] $, le produit est déjà inférieur à $ x $, donc le nombre de formations est de 0 ). Par conséquent, lorsque la somme du nombre minimum de formations pour tout le monde est calculée par $ O (N) $, il suffit qu'elle soit inférieure à $ K $.

Ici, la valeur minimale ($ x ^ {'} $) ** de ** $ x $ peut être trouvée, et $ x $ plus petit que $ x ^ {'} $ ne satisfait pas le thème et $ x ^ Vous pouvez facilement montrer à la ** monotonie ** qu'elle n'est pas satisfaite lorsque $ x $ est supérieur à {'} $, vous pouvez donc rechercher ce $ x ^ {'} $ par dichotomie. (** Vous pouvez y penser du fait que $ x $ croît jusqu'à $ a_ {max} \ times f_ {max} $ en raison de contraintes **.)

D'après ce qui précède, le montant total du calcul est de $ O (N \ log (a_ {max} \ times f_ {max})) $. De plus, si je l'implémentais normalement, cela ne fonctionnerait pas en Python, j'ai donc utilisé PyPy.

<détails>

Code Python </ summary>

abc144e.py


n,k=map(int,input().split())
a=sorted(list(map(int,input().split())))
#Je ne peux pas changer ça
f=sorted(list(map(int,input().split())),reverse=True)
l,r=0,10**12
def cal(x):
    global n,f,a,k
    ret=0
    for i in range(n):
        ret+=max(0,a[i]-(x//f[i]))
    return ret
while l+1<r:
    x=l+(r-l)//2
    if cal(x)<=k:
        r=x
    else:
        l=x
if cal(l)<=k:
    print(l)
else:
    print(r)