首页 > 代码库 > POJ 1651 (区间DP)

POJ 1651 (区间DP)

题目链接: http://poj.org/problem?id=1651

题目大意:加分取牌。如果一张牌左右有牌则可以取出,分数为左牌*中牌*右牌。这样最后肯定还剩2张牌。求一个取牌顺序,使得加分最少。

解题思路

矩阵链乘的变种题。

假设有10、20、30、40、50五张牌。

如果我想要最后取30,则应该先取20、40,这样就还剩10、30、50三张牌了。

不难发现取20是dp[i][k]部分,取40是dp[k][j]部分,最后剩下的就是i、k、j三张牌。

DP边界:无

因为是算加分,区间间隔0、1的情况下dp[i][j]都无法加分,所以默认保留0即可,无须特别预处理。

最后ans=dp[1][n]。

 

#include "cstdio"#include "iostream"using namespace std;#define inf 0x3f3f3f3fint dp[105][105],card[105];int main(){    //freopen("in.txt","r",stdin);    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++)        scanf("%d",&card[i]);    for(int p=2;p<=n;p++)    {        for(int i=1;i<=n-p;i++)        {            int j=i+p;            dp[i][j]=inf;            for(int k=i+1;k<j;k++)                dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+card[i]*card[k]*card[j]);        }    }    printf("%d\n",dp[1][n]);    return 0;}

 

13156701neopenx1651Accepted176K0MSC++664B2014-07-24 14:03:01

 

POJ 1651 (区间DP)