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=位置;iNumber(e)); 常量成本计算器=新的成本计算器(X、Y、S分割(“”) const cost=costCalculator.calculate() log(`Case#${l}:${cost}`) } } main() 这就是我生成重数据集的方式:

import * 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(输入)