PKU 3111 K Best

本文介绍了一个珠宝选择问题的解决方法,旨在帮助一位女士在有限的珠宝中选择价值重量比最高的几种进行保留。通过迭代的方式不断优化选择组合,最终达到价值重量比的最大化。

Description

Demy has n jewels. Each of her jewels has some value vi and weight wi .

Since her husband John got broke after recent financial crises, Demy has decided to sell some jewels. She has decided that she would keep k best jewels for herself. She decided to keep such jewels that their specific value is as large as possible. That is, denote the specific value of some set of jewels S = {i 1 , i 2 , …, ik } as

.

Demy would like to select such k jewels that their specific value is maximal possible. Help her to do so.

Input

The first line of the input file contains n — the number of jewels Demy got, and k — the number of jewels she would like to keep (1 ≤ kn ≤ 100 000).

The following n lines contain two integer numbers each — vi and wi (0 ≤ vi ≤ 106 , 1 ≤ wi ≤ 106 , both the sum of all vi and the sum of all wi do not exceed 107 ).

Output

Output k numbers — the numbers of jewels Demy must keep. If there are several solutions, output any one.

Sample Input

3 2
1 1
1 2
1 3

Sample Output

1 2

这道题的迭代方法我真是不会,希望能通过作越来越多的题突破瓶颈,sigh


 

假设已有的v/w,其中v和w是k个的总和。那么要得到更好的v/w,做法是,求出每一个对于的si,si= vi-wi*v/w

 

 

很容易就能证明si更大的k个,可以组成不比原来小的组合。 设前k个si之和为s;(s最大,如果s>0,迭代没有停止),v/w = (v1-s)/w1<=v1/w1;

 



 
class HMM(object): def __init__(self): self.state_list = ['B','M','E','S'] self.start_p = {} self.trans_p = {} self.emit_p = {} self.model_file = 'hmm_model.pkl' self.trained = False def train(self,datas,model_path=None): if model_path == None: model_path = self.model_file #统计状态频数 state_dict = {} def init_parameters(): for state in self.state_list: self.start_p[state] = 0.0 self.trans_p[state] = {s:0.0 for s in self.state_list} self.emit_p[state] = {} state_dict[state] = 0 def make_label(text): out_text = [] if len(text) == 1: out_text = ['S'] else : out_text += ['B']+['M']*(len(text)-2)+['E'] return out_text init_parameters() line_nb = 0 #监督学习方法求解参数 for line in datas: line = line.strip() if not line: continue line_nb += 1 word_list = [w for w in line if w != ' '] line_list = line.split() line_state = [] for w in line_list: line_state.extend(make_label(w)) assert len(line_state) == len(word_list) for i,v in enumerate(line_state): state_dict[v] += 1 if i == 0: self.start_p[v] += 1 else : self.trans_p[line_state[i-1]][v] += 1 self.emit_p[line_state[i]][word_list[i]] = self.emit_p[line_state[i]].get(word_list[i],0)+1.0 self.start_p = {k: v*1.0/line_nb for k,v in self.start_p.items()} self.trans_p = {k:{k1: v1/state_dict[k1] for k1,v1 in v0.items()} for k,v0 in self.trans_p.items()} self.emit_p = {k:{k1: (v1+1)/state_dict.get(k1,1.0) for k1,v1 in v0.items()} for k,v0 in self.emit_p.items()} with open(model_path,'wb') as f: import pickle pickle.dump(self.start_p,f) pickle.dump(self.trans_p,f) pickle.dump(self.emit_p,f) self.trained = True print('model train done,parameters save to ',model_path) #读取参数模型 def load_model(self,path): import pickle with open(path,'rb') as f: self.start_p = pickle.load(f) self.trans_p = pickle.load(f) self.emit_p = pickle.load(f) self.trained = True print('model parameters load done!') #维特比算法求解最优路径 def __viterbi(self,text,states,start_p,trans_p,emit_p): V = [{}] path = {} for y in states: V[0][y] = start_p[y]*emit_p[y].get(text[0],1.0) path[y] = [y] for t in range(1,len(text)): V.append({}) new_path = {} for y in states: emitp = emit_p[y].get(text[t],1.0) (prob , state) = max([(V[t - 1][y0] * trans_p[y0].get(y, 0) * emitp, y0) \ for y0 in states if V[t - 1][y0] > 0]) V[t][y] = prob new_path[y] = path[state]+[y] path = new_path if emit_p['M'].get(text[-1],0) > emit_p['S'].get(text[-1],0): (prob,state) = max([(V[len(text)-1][y],y) for y in ('E',"M")]) else : (prob,state) = max([(V[len(text)-1][y],y) for y in states]) return (prob,path[state]) def cut(self,text): if not self.trained: print('Error:please pre train or load model parameters') return prob,pos_list = self.__viterbi(text,self.state_list,self.start_p,self.trans_p,self.emit_p) begin_,next_ = 0,0 #任务:完成 HMM 中文分词算法 # ********* Begin *********# # ********* Begin *********# if __name__ == '__main__': text = input() train_data = 'pku_training.utf8' model_file = 'hmm_model.pkl' hmm = HMM() hmm.train(open(train_data, 'r', encoding='utf-8'), model_file) hmm.load_model(model_file) print('/'.join(hmm.cut(text)))
11-29
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值