Algorithm 用记忆显示慢问题解决动态规划问题
我正在学习动态规划。在下面的代码中,我试图将计算出的值存储在内存中(Algorithm 用记忆显示慢问题解决动态规划问题,algorithm,optimization,dynamic-programming,Algorithm,Optimization,Dynamic Programming,我正在学习动态规划。在下面的代码中,我试图将计算出的值存储在内存中(memorization) 但是这个程序仍然很慢。我怎样才能使它更快 我试图解决的问题是2021年CodeJam资格赛的问题 function readInputFile(): Promise<string[]> { const fs = require('fs'); return new Promise((res, rej) => { fs.readFile('random-
memorization
)
但是这个程序仍然很慢。我怎样才能使它更快
我试图解决的问题是2021年CodeJam资格赛的问题
function readInputFile(): Promise<string[]> {
const fs = require('fs');
return new Promise((res, rej) => {
fs.readFile('random-input.txt', 'utf8', (err: null, data: string) => {
if (err) {
console.error(err)
return
}
const lines = data.split("\n")
lines.pop()
res(lines)
})
})
}
function readInput(): Promise<string[]> {
return new Promise((res, rej) => {
const readline = require('readline')
const lines: string[] = []
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
})
rl.on('line', function (line: string) {
lines.push(line)
})
rl.on('close', () => {
// Finished processing input, now solve question
res(lines)
})
})
}
export class Computation {
constructor(public position: number, public choice: string, public lastBeforeChoice: string, public cost: number, public result: number, public row: string[]) {
}
}
export class CostCalculator {
constructor(private X: number, private Y: number, public S: string[]) {
}
calculate() {
const ans = this.recursive(this.S, 0, 0)
// console.log(this.memory.length)
return ans
}
getCost(currentLetter: string, nextLetter: string) {
const pair = [currentLetter, nextLetter].join("")
if (pair === "CJ") {
return this.X
} else if (pair === "JC") {
return this.Y
}
return 0
}
memory: Computation[] = []
compute(row: string[], cost: number, position: number, choice: string) {
const copyC = row.slice()
copyC[position] = choice
const lastBeforeChoice = copyC[position - 1]
const alreadyExisting = this.memory.filter((e) =>
e.position === position && e.cost === cost && e.choice === choice && e.lastBeforeChoice === lastBeforeChoice)[0]
let result = 0
if (alreadyExisting != null) {
result = alreadyExisting.result
} else {
result = this.recursive(copyC, cost, position);
this.memory.push(new Computation(position, choice, lastBeforeChoice, cost, result, copyC))
}
return result - cost
}
recursive(row: string[], cost: number, position: number) {
let costC = 0
let costJ = 0
// looking for the first question mark from left
for (let i = position; i < row.length; i++) {
const s = row[i]
if (s === "?") {
costC = this.compute(row, cost, i, "C")
costJ = this.compute(row, cost, i, "J")
break
} else {
const newCost = this.getCost(row[i - 1], row[i])
cost += newCost
}
}
return Math.min(cost + costC, cost + costJ)
}
}
async function chooseInput() {
if (process.env.USER == "user") {
return readInputFile()
}
return readInput()
}
async function main() {
const lines = await chooseInput();
const T = Number(lines[0])
for (let l = 1; l < lines.length; l++) {
const [x, y, S] = lines[l].split(" ");
const [X, Y] = [x, y].map(e => Number(e));
const costCalculator = new CostCalculator(X, Y, S.split(""))
const cost = costCalculator.calculate()
console.log(`Case #${l}: ${cost}`)
}
}
main()
函数readInputFile():Promise{
常数fs=要求('fs');
返回新承诺((res,rej)=>{
fs.readFile('random-input.txt','utf8',(err:null,data:string)=>{
如果(错误){
控制台错误(err)
返回
}
常量行=数据分割(“\n”)
行。pop()
资源(行)
})
})
}
函数readInput():Promise{
返回新承诺((res,rej)=>{
const readline=require('readline')
常量行:字符串[]=[]
const rl=readline.createInterface({
输入:process.stdin,
输出:process.stdout,
终端:错误
})
rl.on('line',函数(line:string){
线。推(线)
})
rl.on('关闭',()=>{
//完成输入处理,现在解决问题
资源(行)
})
})
}
导出类计算{
构造函数(public position:number,public choice:string,public lastBeforeChoice:string,public cost:number,public result:number,public row:string[])){
}
}
导出类成本计算器{
构造函数(私有X:number,私有Y:number,公共S:string[]){
}
计算(){
const ans=this.recursive(this.S,0,0)
//console.log(this.memory.length)
返回ans
}
getCost(currentLetter:string,nextLetter:string){
常量对=[currentLetter,nextLetter]。联接(“”)
如果(对==“CJ”){
把这个还给我
}否则如果(对==“JC”){
把这个还给我
}
返回0
}
内存:计算[]=[]
计算(行:字符串[],成本:编号,位置:编号,选项:字符串){
const copyC=row.slice()
copyC[位置]=选择
const lastBeforeChoice=copyC[位置-1]
const alreadyExisting=此.memory.filter((e)=>
e、 职位===职位和e.cost===成本和e.choice===选择和e.lastBeforeChoice===lastBeforeChoice)[0]
设结果=0
if(alreadyExisting!=null){
结果=已存在。结果
}否则{
结果=此。递归(复制、成本、位置);
this.memory.push(新计算(位置、选择、上次选择、成本、结果、副本))
}
返回结果-成本
}
递归(行:字符串[],成本:编号,位置:编号){
设costC=0
设costJ=0
//从左开始寻找第一个问号
for(设i=位置;iimport * as fs from 'fs';
const input = ["1000"]
function randomIntFromInterval(min:number, max:number) { // min and max included
return Math.floor(Math.random() * (max - min + 1) + min);
}
for (let n = 0 ; n < 1000 ; n++) {
let S = []
for (let s = 1; s < 1000; s++ ){
S.push(["C", "J", "?"][randomIntFromInterval(0, 2)])
}
const x = randomIntFromInterval(-100, 100)
const y = randomIntFromInterval(-100, 100)
input.push([x, y, S.join("")].join(" "))
}
fs.writeFileSync("random-input.txt", input.join("\n"),);
console.log(input)
import*作为来自“fs”的fs;
常量输入=[“1000”]
函数randomIntFromInterval(最小值:number,最大值:number){//min和max包括在内
返回Math.floor(Math.random()*(max-min+1)+min);
}
for(设n=0;n<1000;n++){
让S=[]
for(设s=1;s<1000;s++){
S.push([“C”,“J”,“?”][randomIntFromInterval(0,2)])
}
常数x=randomIntFromInterval(-100100)
常量y=randomIntFromInterval(-100100)
input.push([x,y,S.join(“”)。join(“”)
}
fs.writeFileSync(“random input.txt”,input.join(“\n”),);
console.log(输入)