zoukankan      html  css  js  c++  java
  • 【u011】乘法难题

    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    乘法难题是一种用一行的卡片来玩的单人游戏,每张卡片上有一个正整数。在游戏者从中拿出一卡片,并且得到一个分数,它等于被拿走的卡片上的数与这张卡片左右两张卡片上的整数的积。第一张与与最后一张卡片不能被拿出。在最后一次移动后,这行卡片中只剩下两张。 你的目标是怎样确定拿卡片的顺序,以使得总分数的值最小。例如,有一行的卡片,它上面的数字为10 1 50 20 5, 游戏者可以先取走1这张卡片,然后是20 和50,总分数为10*1*50 + 50*20*5 + 10*50*5 = 500+5000+2500 = 8000,如果他先拿50, 然接着20,最后取出1, 总分数为1*50*20 + 1*20*5 + 10*1*5 = 1000+100+50 = 1150。


    【输入格式】

    输入文件的第一行包含卡片的总数N(3 <= N <= 100),第二行包含N个范围在1到100之间的整数(两个整数之间有一个空格)

    【输出格式】

    输出文件包含一个整数,为最少的分数。

    【数据规模】

    Sample Input1

    6
    10 1 50 50 20 5
    

    Sample Output1

    3650
    
    【题解】
    设f[i][j]表示从i到j,除了i和j之外都被取走所能得到的最小分数。
    f[i][j] = min(f[i][k]+f[k][j]+a[i]*a[k]*a[j]); i<k<j;
    初值:f[i][i+1] == 0;
    更新方式如下:
    for (int L=2;L<= n;L++)
    for (int s = 1;s <= n-l;s++)
    {
    int t = s+l;
    for (int k = s+1;k<=t-1;k++)
    f[i][j] = min(f[s][k]+f[k][t]+a[i]*a[k]*a[t],f[i][j]);
    }
    最后答案为f[1][n];
    这里一定要先枚举这段的长度。
    这样我们可以先获得像f[1][3],f[2][4],f[3][5]..f[n-2][n]这样的值。
    然后我们在求f[1][4]的时候k在2..3枚举
    f[1][4] = min(f[1][2]+f[2][4]+a[1]*a[2]*a[4],f[1][3]+f[3][4]+a[1]*a[3]*a[4]);
    可以看到我们在求f[1][4]的时候要用到的f[2][4],f[1][3]都已经求出来了 。
    这是原因所在。
    也是这种类型动规的原理->不断利用小的区间扩大区间。
    【代码】
    #include <cstdio>
    #include <cstring>
    
    int a[101],n,f[101][101];
    
    int main()
    {
    	memset(f, 127 / 3, sizeof(f));//一开始f数组赋值为一个很大的数字。
    	scanf("%d", &n);
    	for (int i = 1; i <= n; i++)//读入数据
    		scanf("%d", &a[i]);
    	for (int i = 1; i <= n - 1; i++)//从i到i+1除了i和i+1都不拿 那就是什么都没有。
    		f[i][i + 1] = 0;
    	for (int l = 2;l <= n;l++)//先枚举小的长度。为后面大的长度作铺垫。
    		for (int s = 1; s <= n - l; s++)//枚举起点。
    		{
    			int t = s + l;//这是终点
    			for (int k = s + 1; k <= t - 1; k++)//利用之前得到的小的区间最优值扩大。
    			{
    				int temp = f[s][k] + f[k][t] + a[s] * a[t] * a[k];//f[s][k]里有s,k。f[k][t]也有k,t。
    				//且只剩下k没取。那就把它取下来。看看是否更优。
    				if (temp < f[s][t])
    					f[s][t] = temp;
    			}
    		}
    	printf("%d
    ", f[1][n]);
    	return 0;
    }


  • 相关阅读:
    所有选择器
    display:block、display:inline与displayinline:block的概念和区别
    jQuery 选择器
    JS日历制作获取时间
    HTML DOM 事件
    访问HTML元素(节点)
    HTML常用标签
    flask+mysql的Docker 部署
    docker(三)
    flask如何部署
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632296.html
Copyright © 2011-2022 走看看