Codejam 2010 qualification round question C

来源:互联网 发布:淘宝透明内衣买家晒图 编辑:程序博客网 时间:2024/04/29 14:34

这个大概勉强算是动态规划……吧。

 

'''CodeJam Practice Created on 2013-01-28@author: festony'''from cj_lib import *from properties import *import mathcurr_file_name = 'C-large-practice'#curr_file_name = 'C-small-practice'#curr_file_name = 'test'def input_dividing_func(input_lines):    total_case = int(input_lines.pop(0))    case_inputs = []    for i in range(total_case):        R, k, N = map(int, input_lines.pop(0).split(' '))        g = map(int, input_lines.pop(0).split(' '))        case_inputs.append([R, k, g])    return case_inputsdef run_one_time(g, k, start_from, init_s = 0):    l = len(g)#    if start_from < 0:#        start_from = l + start_from    s = init_s    hit_k = False    for i in range(start_from, l):        if s + g[i] <= k:            s += g[i]        else:            hit_k = True            break    if hit_k:        start_from = i    else:        if s + g[0] > k:            hit_k = True            start_from = 0        else:            s = init_s    return hit_k, start_from, sdef full_run(g, k, start_from, limit_r = -1):    l = len(g)    sub_s = 0    if start_from != 0:        sub_s += sum(g[start_from:])        start_from = 0    S = 0    r = 0    hit_k, start_from, sub_s = run_one_time(g, k, start_from, sub_s)    while hit_k and start_from > 0 and limit_r != r:        S += sub_s        sub_s = 0        r += 1        hit_k, start_from, sub_s = run_one_time(g, k, start_from, sub_s)    if hit_k and limit_r != r:        S += sub_s        r += 1    return r, start_from, S    def process_func(func_input):    R, k, g = func_input    if sum(g) <= k:        return R * sum(g)#    print full_run(g, k, 0, R)    cache_start_from = []    cache = dict()    temp_R = R    start_from = 0    one_round_S = 0    # find out start_from appearing period    while not cache.has_key(start_from) and temp_R > 0:        r, next_start_from, sub_s = full_run(g, k, start_from, temp_R)        cache_start_from.append(start_from)        cache[start_from] = [r, next_start_from, sub_s]        start_from = next_start_from        one_round_S += sub_s        temp_R -= r    # in the process maybe temp_R hit 0. in such case before we find out the period, the result is worked out.    if temp_R == 0:        return one_round_S    S = one_round_S    R = temp_R    R_period = 0    S_period = 0    # after start_from has been found appearing periodically: we need to find the period, because the start_from value may not return to 0.    # e.g. the start_from value may repeat as: 0, 5, 3, 2, 4, 3, 2, 4 ..... so the start_from is repeating 3, 2, 4, need to ignore the previous 0 and 5.    hit_R = False    for s in cache_start_from[cache_start_from.index(start_from, ):]:        r, next_start_from, sub_s = cache[s]        if R_period + r > R:            hit_R = True            break;        R_period += r        S_period += sub_s    # and again, maybe work out the result before find the true period.    if hit_R:        R -= R_period        S += S_period        start_from = s    else:        S += S_period * (R / R_period)        R %= R_period        start_from = next_start_from    while R > 0:        r, next_start_from, sub_s = full_run(g, k, start_from, R)        R -= r        S += sub_s        start_from = next_start_from    return S# to verify the result: this implementation is much slower but can ensure the results are correct.def process_func2(func_input):    R, k, g = func_input    if sum(g) <= k:        return R * sum(g)    S = 0    start_from = 0    while R > 0:        r, next_start_from, sub_s = full_run(g, k, start_from, R)        R -= r        S += sub_s        start_from = next_start_from    return S    run_proc(process_func, input_dividing_func, curr_working_folder, curr_file_name)#run_proc(process_func2, input_dividing_func, curr_working_folder, curr_file_name)


 

原创粉丝点击