dp题:

1、写状态转移方程;

2、考虑初始化边界,有意义的赋定值。还没计算的赋边界值;

3、怎么写代码自底向上计算最优值

今天做了几个基础dp,所有是dp方程写对可是初始化以及计算写错

先是poj 1651 事实上就是个赤裸裸的矩阵连乘。dp方程非常easy写出

dp[i][j]=min(dp[i][k]+dp[k+1][j]+r[i]*c[k]*c[j],dp[i][j]);

先贴两个个二逼的代码,mark下自己多么的二逼:

二逼一:在计算的时候使用了还没有算出来的值,模拟下就知道第一重循环里算dp[0][2]=dp[0][0]+dp[1][2];

!!!!!dp[1][2]这时候根本没有计算出来还,Tmd我就用了这个值!!

。!!!!

!。!

。!

!。!

。。!。。!

二逼啊!

!!!

!。。!

#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int SIZE = 100+10;
const int INF = 10000000;
int dp[SIZE][SIZE];
int r[SIZE],c[SIZE]; int main()
{
    int n;
    while(~scanf("%d",&n))
    {         for(int i=0;i<n-1;i++)
        {
            scanf("%d",&r[i]);
            if(i>0)c[i-1]=r[i];
        }
        scanf("%d",&c[n-2]);
        n--;
        int ans=0;
        for(int i=0;i<n;i++)dp[i][i]=0;         for(int i=0;i<=n;i++)
            for(int j=i;j<n;j++)
            {                 for(int k=i;k<j;k++)
                    dp[i][j]=min(dp[i][k]+dp[k+1][j]+r[i]*c[k]*c[j],dp[i][j]);
            }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
                printf("%d ",dp[i][j]);
            putchar('\n');
        }         printf("%d\n",dp[0][n-1]);     }
    return 0;
}

二逼二:来回换思路的时候各种思路弄混。看凝视

#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int SIZE = 100+10;
const int INF = 10000000;
int dp[SIZE][SIZE];
int r[SIZE],c[SIZE]; int main()
{
int n;
while(~scanf("%d",&n))
{ for(int i=0;i<n-1;i++)
{
scanf("%d",&r[i]);
if(i>0)c[i-1]=r[i];
}
scanf("%d",&c[n-2]);
n--;
int ans=0;
for(int i=0;i<n;i++)dp[i][i]=0;
int j;
for(int l=2;l<=n;l++)
for(int i=0;i<l;i++)//此处i<l及其傻逼,请勿模仿
{
j=i+l-1;
dp[i][j]=INF;
for(int k=i;k<j;k++)
dp[i][j]=min(dp[i][k]+dp[k+1][j]+r[i]*c[k]*c[j],dp[i][j]);
}
/*for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
printf("%d ",dp[i][j]);
putchar('\n');
}*/ printf("%d\n",dp[0][n-1]); }
return 0;
}

正确代码:

#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std;
#define ll long long
const int SIZE = 100+10;
const int INF = 200000000;
ll dp[SIZE][SIZE];
int r[SIZE],c[SIZE]; int main()
{
int n;
while(~scanf("%d",&n))
{ for(int i=0;i<n-1;i++)
{
scanf("%d",&r[i]);
if(i>0)c[i-1]=r[i];
}
scanf("%d",&c[n-2]);
n--;
int ans=0;
for(int i=0;i<=n;i++)dp[i][i]=0;
int j;
for(int l=2;l<=n;l++)
for(int i=0;i<n-l+1;i++)
{
j=i+l-1;
dp[i][j]=INF;
for(int k=i;k<j;k++)
dp[i][j]=min(dp[i][k]+dp[k+1][j]+r[i]*c[k]*c[j],dp[i][j]);
}
printf("%lld\n",dp[0][n-1]); }
return 0;
}

在做这个poj 1651之前  先做的poj 1179,然后过了poj 1651之后改了poj1179原来的循环次序,事实上就是类比这个poj1651,第一重循环弄成长度就可以

注意 负数乘以负数是正数 考虑最大最小值得时候一定注意

只是又一次检查下发现代码在初始化的时候冗余,精简了下。

贴代码:

#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std;
#define ll long long const int SIZE =55;
const int INF = (-2147483647 ) ; ll dp[SIZE][SIZE],dpmin[SIZE][SIZE];
int pos[SIZE];
bool op[SIZE]; int main()
{
//freopen("poj1179.txt","r",stdin);
int n;
ll tmp1,tmp2;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)dp[i][0]=dpmin[i][0]=0;
for(int i=0;i<n;i++)
{
scanf(" %c %lld",&op[i],&dp[i][1]);
dpmin[i][1]=dp[i][1];
}
for(int j=1;j<=n;j++)
for(int i=0;i<n;i++)
{
if(j>1)dp[i][j]=INF,dpmin[i][j]=-INF;
for(int k=1;k<j;k++)
{
if(op[(i+k)%n ] == 't')
{
dp[i%n][j]=max(dp[i%n][k]+dp[(i+k)%n ][j-k],dp[i%n][j]);
dpmin[i%n][j]=min(dpmin[i%n][k]+dpmin[(i+k)%n ][j-k], dpmin[i%n][j]);
} else
{
tmp1=max(dp[i%n][k]*dp[(i+k)%n ][j-k],dpmin[i%n][k]*dpmin[(i+k)%n ][j-k]);
tmp2=max(dp[i%n][k]*dpmin[(i+k)%n ][j-k], dpmin[i%n][k]*dp[(i+k)%n ][j-k]);
tmp1=max(tmp1,tmp2);
dp[i%n][j]=max(tmp1,dp[i%n][j]);
tmp2=min(dp[i%n][k]*dp[(i+k)%n ][j-k],dpmin[i%n][k]*dpmin[(i+k)%n ][j-k]);
tmp1=min(dp[i%n][k]*dpmin[(i+k)%n ][j-k], dpmin[i%n][k]*dp[(i+k)%n ][j-k]);
tmp2=min(tmp1,tmp2);
dpmin[i%n][j]=min(dpmin[i%n][j],tmp2);
} }
}
int cnt=0;
ll ans=INF;
for(int i=0;i<n;i++)//開始的时候,这里i<=n。于是初始化的时候必须优dp[n][...]=INF,才干AC,奇怪的是计算过程中第一个下标我都%n了,最后才看到这里的问题
{
ans=max(ans,dp[i][n]);
}
for(int i=0;i<n;i++)
if(ans == dp[i][n])
pos[cnt++]=i+1; printf("%lld\n",ans);
for(int i=0;i<cnt;i++)
if(i == cnt-1)printf("%d\n",pos[i]);
else printf("%d ",pos[i]);
} return 0;
}

Mark一下, dp状态转移方程写对,可是写代码都错,poj 1651 poj 1179的更多相关文章

  1. poj2385 Apple Catching(dp状态转移方程推导)

    https://vjudge.net/problem/POJ-2385 猛刷简单dp的第一天的第一题. 状态:dp[i][j]表示第i秒移动j次所得的最大苹果数.关键要想到移动j次,根据j的奇偶判断人 ...

  2. DP 状态 DP 转移方程 动态规划解题思路

    如何学好动态规划(2) 原创 Gene_Liu LeetCode力扣 今天 算法萌新如何学好动态规划(1) https://mp.weixin.qq.com/s/rhyUb7d8IL8UW1IosoE ...

  3. hdu 动态规划(46道题目)倾情奉献~ 【只提供思路与状态转移方程】(转)

    HDU 动态规划(46道题目)倾情奉献~ [只提供思路与状态转移方程] Robberies http://acm.hdu.edu.cn/showproblem.php?pid=2955      背包 ...

  4. 【转载】 HDU 动态规划46题【只提供思路与状态转移方程】

    1.Robberies 连接 :http://acm.hdu.edu.cn/showproblem.php?pid=2955      背包;第一次做的时候把概率当做背包(放大100000倍化为整数) ...

  5. dp状态压缩

    dp状态压缩 动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的就是那种状态很多,不容易用一般的方法表示的动态规划问题,这个就更加的难于把握了.难点在于以下几个方面:状 ...

  6. 1113: [视频]树形动态规划(TreeDP)8:树(tree)(树形dp状态设计总结)

    根据最近做的几道树形dp题总结一下规律.(从这篇往前到洛谷 P1352 ) 这几道题都是在一颗树上,然后要让整棵树的节点或边 满足一种状态.然后点可以影响到相邻点的这种状态 然后求最小次数 那么要从两 ...

  7. Codeforces 889E - Mod Mod Mod(dp+状态设计)

    Codeforces 题目传送门 & 洛谷题目传送门 题目名称 hopping 我们记 \(x_i=X\bmod a_1\bmod a_2\bmod\dots\bmod a_i\),也就是 \ ...

  8. HDU 4628 Pieces(DP + 状态压缩)

    Pieces 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4628 题目大意:给定一个字符串s,如果子序列中有回文,可以一步删除掉它,求把整个序列删除 ...

  9. P2157 [SDOI2009]学校食堂 (dp+状态压缩)

    题目链接:传送门 题目: 题目描述 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人 ...

随机推荐

  1. [oldboy-django][2深入django]班级管理(Form)--添加

    1.需求: 添加班级,当有某个输入框数据格式不对时,会保留所有输入框的上次输入数据, 同时给出错误信息 2.视图 def add_class(request): # 提交数据都要用form来实现,因为 ...

  2. 模板与c++11--右值引用

    函数参数传递 struct huge_data{ char *content; unsigned sz; huge_data():content(),sz(){ cout<<this< ...

  3. c语言有用函数收集

    1 strtok :分解字符串为一组字符串.s为要分解的字符串,delim为分隔符字符串.首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL. 2 strstr :从字符串str1中查找 ...

  4. BZOJ 1564 :[NOI2009]二叉查找树(树型DP)

    二叉查找树 [题目描述] 已知一棵特殊的二叉查找树.根据定义,该二叉查找树中每个结点的数据值都比它左儿子结点的数据值大,而比它右儿子结点的数据值小. 另一方面,这棵查找树中每个结点都有一个权值,每个结 ...

  5. 减法要用 signed 型

    今天调试一个程序,因为Feedback是电流采样值,Setpoint是PWM值,这两个不可能是负值.所以以为Setpoint和Feedback这两个变量都可以设置为u16型(unsigned int) ...

  6. BZOJ3772 精神污染 【主席树 + dfs序】

    题目 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位是森林和山地,与拥有关西机场的大阪府比邻而居,是关西地区面积最大的县,是集经济和文化于一体的一大地区,是日本西部门户,海 ...

  7. 无序字母对 character

    无序字母对 character 题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入 ...

  8. mongodb学习(3)--- NodeJs使用mongoose操作mongodb

    转载: https://cnodejs.org/topic/50c145ed637ffa4155c7eaee 首先对于以下错误说明(有写 db.close): Error: db object alr ...

  9. ThreadPool学习草稿1

    原文发布时间为:2010-10-27 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Collections.Generic;using Syste ...

  10. SQL索引碎片整理脚本

    原文发布时间为:2011-02-23 -- 来源于本人的百度文章 [由搬家工具导入] reindex是比较好的选择,速度快,但是他不能在线操作INDEXDEFRAG 比较慢,但是可以在线操作rebui ...