POJ 1651 区间DP Multiplication Puzzle

此题可以转化为最优矩阵链乘的形式,d(i, j)表示区间[i, j]所能得到的最小权值。

枚举最后一个拿走的数a[k],状态转移方程为d(i, j) = min{ d(i, k) + d(k, j) + a[i] * a[k] * a[j] }

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6
 7 const int maxn = 100 + 10;
 8 const int INF = 0x3f3f3f3f;
 9
10 int n;
11
12 int a[maxn];
13 int d[maxn][maxn];
14
15 int DP(int i, int j)
16 {
17     if(j <= i + 1) return 0;
18     int& ans = d[i][j];
19     if(ans >= 0) return ans;
20     ans = INF;
21     int t = a[i] * a[j];
22     for(int k = i + 1; k < j; k++) ans = min(ans, DP(i, k) + DP(k, j) + t * a[k]);
23     return ans;
24 }
25
26 int main()
27 {
28     while(scanf("%d", &n) == 1 && n)
29     {
30         for(int i = 0; i < n; i++) scanf("%d", a + i);
31         memset(d, -1, sizeof(d));
32         printf("%d\n", DP(0, n - 1));
33     }
34
35     return 0;
36 }

代码君

时间: 2024-10-11 15:22:46

POJ 1651 区间DP Multiplication Puzzle的相关文章

poj 1651 区间dp

题目链接:http://poj.org/problem?id=1651 Description The multiplication puzzle is played with a row of cards, each containing a single positive integer. During the move player takes one card out of the row and scores the number of points equal to the prod

POJ 区间DP Multiplication Puzzle

The multiplication puzzle is played with a row of cards, each containing a single positive integer. During the move player takes one card out of the row and scores the number of points equal to the product of the number on the card taken and the numb

poj 1651(区间dp)

乱改出真知,做不动了,水平有限,大概了解一下,去做树形dp了,以后回来再学 #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; const int maxn=100+10; int a[maxn]; int dp[maxn][maxn]; int n; const int inf=0x3f3f3f3f; int m

poj 3280(区间DP)

Cheapest Palindrome Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7869   Accepted: 3816 Description Keeping track of all the cows can be a tricky task so Farmer John has installed a system to automate it. He has installed on each cow a

DP:Multiplication Puzzle(POJ 1651)

卡片游戏 题目大意:给你一排卡片,你可以从从中抽一些卡片(但是不能抽最左和最右的卡片),每张卡片上有一个数字,当你从中抽出一张卡片后,你将得卡片的数字和卡片左右两张卡片的数字的乘积的分数,问当剩下最左和最右两张卡片的时候,你可以得到的最小的分数? 这一题一看好像挺复杂的,但是如果我们换一个思维方式,这一题就会变得很熟悉 首先这一题是显而易见的DP(找最小值,不能取极限方式) 首先他要我们抽卡片是吧,一开始我们可能会想到先抽一张看看,然后在扫一遍其他卡片看能否抽,但是这样带来的直接后果就是,我们很

poj 1141 区间dp

题目链接:http://poj.org/problem?id=1141 题解:略 代码: #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define ll long long const int maxn=1e2+5; const int INF=0x3f3f3f3f; int dp[105][105]; int

poj 3186区间dp

给你一个数列   然后从里面取数  只能从队头或队尾取出   取出的值乘以取出的顺序i(及第几个取出的)  求累加和的最大值: dp[i][j]表示去了i次   从左边去了j个的最大值:  然后地推下去: dp[i][j]=max(dp[i-1][j]*num[j]*i,num[i-1][j]+num[n-i+j+1]*i)注意j为0的情况:再说这道题坑吧     num数组开为局部变量wa   开为int64  还是wa  真是无语了 #include<stdio.h> #include&l

poj 2955 区间dp(括号匹配)

#include<stdio.h> #include<string.h> #include<iostream> using namespace std; int max(int a,int b) { return a>b?a:b; } int main() { char str[110]; int dp[110][110]; int i,j; while(~scanf("%s",str)) { int len=strlen(str); if(s

poj 1141 区间dp+递归打印路径

Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30383   Accepted: 8712   Special Judge Description Let us define a regular brackets sequence in the following way: 1. Empty sequence is a regular sequence. 2. If S is a re