zoukankan      html  css  js  c++  java
  • 2004选拔赛 最小值

    给出S和T个整数集合,分别含有n和m个元素(n<=m<=500),问

               

    的最小值。

    如果a>b && c>d,有|a-c|=|b-d| >= |a-d| + |b-c|(不妨设c>a,然后对d与a,b的大小讨论,可以去掉绝对值符号证明),要对S和T排序。

    动态规划,if ( i == j) f[i,j] = f[i-1, j-1] + abs( s[i] - t[j] ) ,所以边界条件有 f[0,0] = 0;

    if (j > i) f[i, j] = min( f[i, j-1], f[i-1, j-1]+abs( s[i] - t[j] ) ),所以另一个边界条件是f[0, k] = 0 (k > 0).

    记忆化搜索。

    # include <stdio.h>
    # include <stdlib.h>
    # include <math.h>
    
    # define N 500 + 5
    
    int n, m;
    int s[N], t[N];
    int f[N][N];
    
    int min(int x, int y)
    {
        return x < y ? x : y;
    }
    
    int cmp(const void *x, const void *y)
    {
        return *(int*)x > *(int*)y ? 1 : -1;
    }
    
    int dp(int i, int j)
    {
        if (f[i][j] >= 0) return f[i][j];
        if (i == 0) return f[i][j] = 0;
        if (i == j) return f[i][j] = dp(i-1, j-1) + abs(s[i]-t[j]);
        return f[i][j] = min(dp(i, j-1), dp(i-1, j-1)+abs(s[i]-t[j]));
    }
    
    void init(void)
    {
        int i;
    
        scanf("%d%d", &n, &m);
        for (i = 1; i <= n; ++i)
            scanf("%d", &s[i]);
        for (i = 1; i <= m; ++i)
        {
            memset(f[i], -1, sizeof(f[i]));
            scanf("%d", &t[i]);
        }
        qsort(s+1, n, sizeof(s[0]), cmp);
        qsort(t+1, m, sizeof(t[0]), cmp);
    }
    
    void solve(void)
    {
        int i, j;
        int ans = dp(n, m);
        printf("%d\n", ans);
    }
    
    int main()
    {
        int T;
    
        scanf("%d", &T);
        while (T--)
        {
            init();
            solve();
        }
    
        return 0;
    }

    /**/

  • 相关阅读:
    第四周助教小结 北软
    第二周工作小结 北软
    第六周助教小结 北软
    第七周周小结 北软
    第八周周小结 北软
    几句话了解元数据(Metadata)
    App测试点(二)
    Pytest单元测试
    UnitTest单元测试
    【模板】单源最短路径
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2603424.html
Copyright © 2011-2022 走看看