zoukankan      html  css  js  c++  java
  • PKU acm 1651 multiplication puzzle

    10 1 50 20 5

    player might take a card with 1, then 20 and 50, scoring

    10*1*50 + 50*20*5 + 10*50*5 = 500+5000+2500 = 8000

    If he would take the cards in the opposite order, i.e. 50, then 20, then 1, the score would be

    1*50*20 + 1*20*5 + 10*1*5 = 1000+100+50 = 1150.

    不能取第一个和最后一个数字,我们的目的是将其余数字全部取出,并且使得按照规则计算的分数最小。

    计分规则是,每取一个a, 计算 score.a = a.left * a * a.right然后将a取出,最后的总分是每次取出计算得出的分值总和。

     

    动态规划,思路和矩阵连乘几乎一致。

    考虑

    10 1 50 20 5

    对于最优解,取最后一个数字,假如说最后一个数字取的是50,那么其实

    10 1 50

    50 20 5

    是两个子问题,他们也应该是最优的,而最后结果是

    10 * 50 * 5 + best(10,1,50) + best(50,20,5)

     

    best resutl  of li = best[0, len – 1]

     

    best[i, j] =  min { li[i] * li[k] * li[j] + best[i, k] + best[k, j]} for k in range [i+1, j)

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int SolveDp(int a[], int num)
     5 {
     6     int result[num][num];
     7     for (int i = 0; i < num; i++)
     8         for (int j = 0; j < num; j++)
     9             result[i][j] = 0;
    10 
    11     //init delta = 2 a[0] a[1] a[2]
    12     for (int i = 0; i < num - 2; i++)
    13         result[i][i + 2= a[i] * a[i + 1* a[i + 2];
    14 
    15     for (int delta = 3; delta < num; delta++)
    16         for (int i = 0; i < num - delta; i++) {
    17             int minScore;
    18             for (int j = i + 1; j < i + delta; j++) {
    19                 int curScore = result[i][j] + result[j][i + delta] + 
    20                                a[i] * a[j] * a[i +delta];
    21                 if(j == i + 1)
    22                     minScore = curScore;
    23                 else if (curScore < minScore)
    24                     minScore = curScore;
    25             }
    26             result[i][i + delta] = minScore;
    27         }
    28     return result[0][num - 1];
    29 }
    30 
    31 int main(int argc, char *argv[])
    32 {
    33     //while(1) {
    34         int num;
    35         cin >> num;
    36         int a[num];
    37         for (int i = 0; i < num; i++)
    38             cin >> a[i];
    39         cout << SolveDp(a, num) << endl;
    40     //}
    41     return 0;
    42 }

    下面给出python写的,递归回溯(穷举),以及动态规划解法

     1 #递归回溯穷举
     2 def findMinScore(li):
     3     minScore = -1  #init,if not touched it will be < 0
     4     def findMinScoreRec(score = 0):
     5         nonlocal minScore
     6         length = len(li)
     7         for i in range(1, length - 1):
     8             val = li[i]
     9             newScore =  score + li[i - 1* val * li[i + 1]
    10             if not minScore < 0 and newScore > minScore:
    11                 return
    12             if len(li) == 3:
    13                 if minScore <or newScore < minScore:
    14                     minScore = newScore
    15                 return
    16             li.pop(i)
    17             findMinScoreRec(newScore)
    18             li.insert(i, val)  #do not need to get back
    19     print("min score is ", minScore);        
    20     findMinScoreRec();
    21     return minScore
    22  1 #dp method
     2 def findMinScore(li):
     3     length = len(li)
     4     #below is wrong!!! when result[0][2] = 99 than result[i][2] = 99 why??
     5     #result = [[0] * length] * length  #result[length][length] 0 is must for elements of distance 2
     6     
     7     result = [[0   for   a   in   range(length)]   for   b   in   range(length)]
     8     
     9     for i in range(length - 2):
    10         result[i][i + 2= li[i] * li[i + 1* li[i + 2]
    11     
    12     for delta in range(3, length):
    13         for i in range(length - delta):
    14             for j in range(i + 1, i + delta):
    15                 curScore = result[i][j] + result[j][i + delta] \
    16                     + li[i] * li[j] * li[i + delta]
    17                 if (j == i + 1 or curScore < minScore):
    18                     minScore = curScore
    19             result[i][i + delta] = minScore
    20     
    21     return result[0][length - 1]
    22 

  • 相关阅读:
    2018年工作总结
    通过js date对象获取各种开始结束日期的示例
    位运算
    Nhibernate官方体系结构图部分中文翻译
    javascript中判断变量是否存在的正确方式
    .net core 项目加载提示项目文件不完整缺少预期导入的解决办法
    dotnet core 运行程序注意事项
    关于.net 项目 nuget包还原项目失败的记录
    c#利用反射实现对类中的常量进行取值和对应常量的注释
    在ie9下在textbox框里面输入内容按enter键会触发按钮的事件
  • 原文地址:https://www.cnblogs.com/rocketfan/p/1569923.html
Copyright © 2011-2022 走看看