• UVA 531 Compromise


    最长公共子序列问题,打印路径总结了两个方法,一个是递归指向,就像前面做的01背包问题如:

    for(int i = 1; i < n; i ++)
    for(int j = 0; j < n-i; j ++)
    for(int k = j; k < i+j; k ++)
    {
    if(k == j)
    {
    f[j][i+j] = f[j][k]+f[k+1][i+j]+A[j][0]*A[k][1]*A[i+j][1];
    part1[j][i+j] = k;//赋值
    }
    if(f[j][k]+f[k+1][i+j]+A[j][0]*A[k][1]*A[j+i][1] < f[j][i+j])
    {
    f[j][i+j] = f[j][k]+f[k+1][i+j]+A[j][0]*A[k][1]*A[j+i][1];
    part1[j][i+j] = k;//赋值
    }
    }
    
    
    void printpath(int a, int b)//输出
    {
    if(a == b)
    {
    printf("A%d", a + 1);
    return ;
    }
    printf("(");
    printpath(a, part1[a][b]);
    printf(" x ");
    printpath(part1[a][b] + 1, b);
    printf(")");
    }
    例如:
    
    
    for(int i = 1; i <= cdnum; i ++)
    for(int j = 0; j <= tap; j ++)
    {
    f[i][j] = f[i-1][j];
    p[i][j] = j;//赋值
    if(j>=num[i]&&f[i-1][j-num[i]]+num[i] > f[i][j])
    {
    f[i][j] = f[i-1][j-num[i]]+num[i]; p[i][j] = j-num[i];//赋值
    }
    }
    
    
    void print(int i, int j)//打印路径
    {
    if(i == 0)
    return;
    print(i - 1, p[i][j]);
    if(p[i][j] < j)
    printf("%d ", num[i]);
    }
    这第二种就是今天用到的 赋值遍历打印路径;
    
    
        for(int i = 1; i <= m; i ++)
    for(int j = 1; j <= n; j ++)
    if(!strcmp(a[i], b[j]))
    {
    f[i][j] = f[i-1][j-1] + 1;
    p[i][j] = 1;//赋值
    }
    else if(f[i-1][j]>f[i][j-1])
    {
    f[i][j] = f[i-1][j];
    p[i][j] = 0;//赋值
    }
    else
    {
    f[i][j] = f[i][j-1];
    p[i][j] = -1;//赋值
    }

    void print(int i , int j)//输出
    {
    if(!i || !j)
    return ;
    if(p[i][j] == 1)
    {
    print(i-1,j-1);
    if(flag)
    printf(" ");
    else
    flag = 1;
    printf("%s", a[i]);
    }
    else if(p[i][j] == 0)
    print(i-1,j);
    else print(i,j-1);
    }

    代码如下:
    
    
    #include<stdio.h>
    #include<string.h>
    #define MAXN 100 + 5
    char a[MAXN][35], b[MAXN][35], f[MAXN][MAXN], p[MAXN][MAXN];
    int m, n, flag;
    void print(int i , int j)
    {
    if(!i || !j)
    return ;
    if(p[i][j] == 1)
    {
    print(i-1,j-1);
    if(flag)
    printf(" ");
    else
    flag = 1;
    printf("%s", a[i]);
    }
    else if(p[i][j] == 0)
    print(i-1,j);
    else print(i,j-1);
    }
    void solve()
    {
    memset(f,0,sizeof(f));
    for(int i = 1; i <= m; i ++)
    for(int j = 1; j <= n; j ++)
    if(!strcmp(a[i], b[j]))
    {
    f[i][j] = f[i-1][j-1] + 1;
    p[i][j] = 1;
    }
    else if(f[i-1][j]>f[i][j-1])
    {
    f[i][j] = f[i-1][j];
    p[i][j] = 0;
    }
    else
    {
    f[i][j] = f[i][j-1];
    p[i][j] = -1;
    }
    print(m,n);
    printf("\n");
    }
    void input()
    {
    while(scanf("%s",a[1]) == 1)
    {
    flag = 0;
    m = 1;
    n = 0;
    if(a[1][0] != '#')
    for(int j = 2; ;j ++)
    {
    scanf("%s",a[j]);
    if(a[j][0] == '#') break;
    m ++;
    }
    for(int i = 1; ; i ++)
    {
    scanf("%s",b[i]);
    if(b[i][0] == '#') break;
    n ++;
    }
    solve();
    }
    }
    int main()
    {
    input();
    return 0;
    }





  • 相关阅读:
    luoguP1919 A*B Problem升级版 ntt
    luogu[愚人节题目3]现代妖怪殖民地 NTT
    FFT 快速傅里叶变换 学习笔记
    十二省联考 爆0记
    # NOI.AC省选赛 第五场T1 子集,与&最大值
    2019.6.16完成classstack任务
    USACO-集合
    USACO-修理牛棚
    dij模板
    洛谷P1948 [USACO08JAN]电话线Telephone Lines
  • 原文地址:https://www.cnblogs.com/yuzhaoxin/p/2407721.html
Copyright © 2020-2023  润新知