page section no title submit
113 1.5.1 例题1 括号序列 POJ1141
116 1.5.1 例题2 棋盘分割 POJ1191
117 1.5.1 例题3 决斗 117 1.5.1 例题4 “舞蹈家”怀特先生 ACM-ICPC Live Archive
119 1.5.1 例题5 积木游戏 http://202.120.80.191/problem.php?problemid=1244
123 1.5.2 例题1 方块消除 http://poj.org/problem?id=1390
123 1.5.2 例题2 公路巡逻 http://202.120.80.191/problem.php?problemid=1600
125 1.5.2 例题3 并行期望值 POJ1074
131 1.5.2 例题6 不可分解的编码 http://acmicpc-live-archive.uva.es/nuevoportal/data/problem.php?p=2475
133 1.5.2 例题7 青蛙的烦恼 http://codewaysky.sinaapp.com/problem.php?id=1014
135 1.5.2 例题9 最优排序二叉树 http://judge.noi.cn/problem?id=1059
138 1.5.2 例题10 Bugs公司 POJ1038
139 1.5.2 例题11 迷宫统计 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=70&page=show_problem&problem=1472
142 1.5.2 例题12 贪吃的九头龙 http://judge.noi.cn/problem?id=1043
151 1.5.3 问题2 最长上升子序列问题 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=17&page=show_problem&problem=1475
151 1.5.3 问题3 最优二分检索树 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=15&page=show_problem&problem=1245
152 1.5.3 问题4 任务调度问题 POJ1180
121 1.5.1 1.5.8 艺术馆的火灾 http://221.192.240.23:9088/showproblem?problem_id=1366
144 1.5.2 1.5.10 快乐的蜜月 http://judge.noi.cn/problem?id=1052
145 1.5.2 1.5.12 佳佳的筷子 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=14&page=show_problem&problem=1212
146 1.5.2 1.5.13 偷懒的工人 POJ1337
146 1.5.2 1.5.15 平板涂色 POJ1691
147 1.5.2 1.5.16 道路重建 POJ1947
147 1.5.2 1.5.17 圆和多边形 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1679
148 1.5.2 1.5.18 Jimmy落地 POJ1661
148 1.5.2 1.5.19 免费糖果 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=13&page=show_problem&problem=1059
157 1.5.3 1.5.22 回文词 POJ1159
157 1.5.3 1.5.24 邮局 POJ1160
158 1.5.3 1.5.26 奶牛转圈 POJ1946
158 1.5.3 1.5.27 元件折叠 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=14&page=show_problem&problem=1180

现在开始训练一下DP:

pku 1141 Brackets Sequence

黑书上讲的第一个题目,题意就给出一个括号序列,包含有"(" ")" "[" "]" 求最少添加的括号数是的最终的序列是合法的并输出这个序列。

思路:
首先这里求解的话要使用递归的思路,这是动态规划产生的第一种动机,于是我们可以写出记忆化搜索。进行求解。

dp[l][r] = min(dp[l][r],dp[l + 1][r - 1])如果s[l]与s[r]匹配的话。

否则我们就将该序列分成两段分别求解(这也是求解DP线性模型的一种递归分解思路)

dp[l][r] = min(dp[l][r],dp[l][k] + dp[k + 1][r])

这里关键是怎么讲可行解输出呢?开始我是通过比较dp[l][r] 与 dp[l + 1][r  -1] dp[l][k] + dp[k + 1][r]来判断的后来发现这样不对的 如果dp[l + 1][r - 1] = dp[l][k] + dp[k + 1][r]的话就会出现错误,而我们这里dp[l][r]确实从dp[l][k] + dp[k + 1][r]来的。所以,我们要另开一个二维数组记录每种最优状态的来源点。然后再递归的输出即可。

View Code
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define ll __int64
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);


#define M 137
#define N 115

using namespace std;


const int inf = 0x7f7f7f7f;
const int mod = 1000000007;

int dp[N][N];
char s[N];
int mk[N][N];

bool cmp(char a,char b)
{
    if ((a == '(' && b == ')') || (a == '[' && b == ']')) return true;
    return false;
}
int dfs_DP(int l,int r)
{
    int k;
    if (l > r) return 0;
    if (l == r) return (dp[l][r] = 1);
    if (dp[l][r] != inf) return dp[l][r];

    if (cmp(s[l],s[r]))
    {
        if (l + 1 == r)
        {
            dp[l][r] = 0;
            mk[l][r] = -1;
        }
        else
        {
            dfs_DP(l + 1,r - 1);
            if (dp[l][r] > dp[l + 1][r - 1])
            {
                dp[l][r] = dp[l + 1][r - 1];
                mk[l][r] = -1;
            }

    //        dp[l][r] = min(dp[l][r],dfs_DP(l + 1,r - 1));
//             printf(">>>**%d %d %d %d\n",l,r,dp[l][r],dp[l + 1][r - 1]);
        }
    }

    for (k = l; k <= r - 1; ++k)
    {
        dfs_DP(l,k); dfs_DP(k + 1,r);
        if (dp[l][r] >  dp[l][k] + dp[k + 1][r])
        {
            dp[l][r] = dp[l][k] + dp[k + 1][r];
            mk[l][r] = k;
        }
//        dp[l][r] = min(dp[l][r],dfs_DP(l,k) + dfs_DP(k + 1,r));
    }
    return dp[l][r];
}


void print(int l,int r)
{
    if (l > r) return;
    if (l == r)
    {
        if (s[l] == '(' || s[l] == ')') printf("()");
        else if (s[l] == '[' || s[l] == ']') printf("[]");
        return;
    }
    if (cmp(s[l],s[r]) && mk[l][r] == -1)
    {
        printf("%c",s[l]);
        print(l + 1,r - 1);
        printf("%c",s[r]);
    }
    else
    {
        print(l,mk[l][r]);
        print(mk[l][r] + 1,r);
    }
}
int main()
{
//   Read();
//   Write();
   int i,j;
   scanf("%s",s);
   int n = strlen(s);
   CL(mk,-1);
   for (i = 0; i <= n; ++i)
   {
       for (j = 0; j <= n; ++j)
       {
           dp[i][j] = inf;
       }
   }
   dfs_DP(0,n - 1);
//   printf("%d\n",dp[0][n - 1]);
   print(0,n - 1);
   printf("\n");
   return 0;
}

 

 pku 1191 棋盘分割

思路:
棋盘横着切竖着切,然后递归将棋盘不断缩小到能够求解的状态。记忆化搜索。这里中间计算值可能会超0x7f7f7f7f,所以最大值取大一点。这里让哥条了很长时间。。

View Code
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define ll __int64
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);


#define M 137
#define N 10

using namespace std;


const int inf = 0x7f7f7f7f;
const int mod = 1000000007;

int mat[N][N];
int s[N][N][N][N];
int dp[N][N][N][N][20];
ll map[N][N];

int n;

int DP(int x1,int y1,int x2,int y2,int no)
{
    int x,y;
    if (no == 1) return dp[x1][y1][x2][y2][no];
    if (dp[x1][y1][x2][y2][no] != -1) return dp[x1][y1][x2][y2][no];
    int ans = 999999999;
    for (x = x1; x < x2; ++x)
    {
        ans = min(ans,min(DP(x1,y1,x,y2,no - 1) + s[x + 1][y1][x2][y2],DP(x + 1,y1,x2,y2,no - 1) + s[x1][y1][x][y2]));
    }
    for (y = y1; y < y2; ++y)
    {
          ans = min(ans,min(DP(x1,y1,x2,y,no - 1) + s[x1][y + 1][x2][y2],DP(x1,y + 1,x2,y2,no - 1) + s[x1][y1][x2][y]));
    }
    return (dp[x1][y1][x2][y2][no] = ans);
}
int main()
{
//    Read();
    int i,j;
    scanf("%d",&n);
    int sum = 0;
    for (i = 1; i <= 8; ++i)
    {
        for (j = 1; j <= 8; ++j)
        {
            scanf("%d",&mat[i][j]);
            sum += mat[i][j];
        }
    }

    CL(s,0); CL(dp,-1);
    int x1,y1,x2,y2;
    for (x1 = 1; x1 <= 8; ++x1)
    {
        for (y1 = 1; y1 <= 8; ++y1)
        {
            for (x2 = x1; x2 <= 8; ++x2)
            {
                for (y2 = y1; y2 <= 8; ++y2)
                {
//                    printf("%d %d %d %d\n",x1,y1,x2,y2);
                    for (i = x1; i <= x2; ++i)
                    {
                        for (j = y1; j <= y2; ++j)
                        {
                            s[x1][y1][x2][y2] += mat[i][j];
                        }
                    }

                    s[x1][y1][x2][y2] *=  s[x1][y1][x2][y2];

                    dp[x1][y1][x2][y2][1] = s[x1][y1][x2][y2];
                }
            }
        }
    }


    DP(1,1,8,8,n);
    double ans = (1.0*dp[1][1][8][8][n])/(1.0*n) - (1.0*sum*sum)/(1.0*n*n);
    printf("%.3f\n",sqrt(ans));
    return 0;
}

 

 sicily 1822  View Code

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define ll __int64
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);


#define M 137
#define N 50

using namespace std;

const int inf = 0x7f7f7f7f;
const int mod = 1000000007;

int mat[N][N];

int dp[N][N];
int seq[N];
bool vt[N][N];

int n;
int DP(int l,int r)
{
    int k;
    if (vt[l][r]) return dp[l][r];

    for (k = l + 1; k <= r - 1; ++k)
    {
        dp[l][r] = (DP(l,k)&&DP(k,r)&&(mat[seq[l]][seq[k]] || mat[seq[r]][seq[k]]));
        if (dp[l][r]) break;
    }
    vt[l][r] = true;
    return dp[l][r];
}
int main()
{
//    Read();
    int T,i,j;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d",&n);
        CL(mat,0);
        for (i = 1; i <= n; ++i)
        for (j = 1; j <= n; ++j)
        scanf("%d",&mat[i][j]);


        for (i = 1; i <= n; ++i)
        {
            CL(dp,0); CL(vt,false);

            int pos = (i - 1);
            if (pos == 0) pos = n;

            int ln = 0;
            for (j = i; j <= n; ++j) seq[++ln] = j;
            for (j = 1; j <= i - 1; ++j) seq[++ln] = j;
            seq[++ln] = n + 1;

            for (j = 1; j <= n; ++j)
            {
                dp[j][j + 1] = dp[j + 1][j] = 1;
                vt[j][j + 1] = vt[j + 1][j] = true;
            }

            DP(1,ln);
            if (dp[1][ln]) printf("1\n");
            else printf("0\n");
        }
//        if (T != 0)
        printf("\n");
    }

    return 0;
}

相关文章:

  • 2021-10-20
  • 2022-01-18
  • 2021-07-28
  • 2022-12-23
  • 2021-09-05
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-09-16
  • 2022-12-23
  • 2021-07-04
  • 2021-10-18
  • 2021-07-13
  • 2021-12-25
  • 2021-11-20
相关资源
相似解决方案