• DAG上的动态规划


    嵌套矩形问题(最长路及其字典序)
    有n个举行,选出尽量多的矩阵排成一排,使得除了最后一个之外,每一个矩形可以嵌套在下一个矩形内,并且打印

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <stack>
    #include <cctype>
    #include <string>
    #include <queue>
    #include <map>
    #include <set>
    
    using namespace std;
    
    const int INF = 0xffffff;
    const double esp = 10e-8;
    const double Pi = 4 * atan(1.0);
    const int maxn =  100+ 10;
    const long long mod =  1000000007;
    const int dr[] = {1,0,-1,0,-1,1,-1,1};
    const int dc[] = {0,1,0,-1,1,-1,-1,1};
    typedef long long LL;
    
    LL gac(LL a,LL b){
        return b?gac(b,a%b):a;
    }
    int n;
    bool graph[maxn][maxn];
    struct G{
        int a,b;
    };
    G g[maxn];
    int d[maxn][maxn];
    bool judge(int x,int y){
        if(g[x].a < g[y].a && g[x].b < g[y].b)
            return 1;
        if(g[x].a < g[y].b && g[x].b < g[y].a)
            return 1;
        return 0;
    }
    int dp(int i,int tt){
        if(d[tt][i] > 0)
            return d[tt][i];
        d[tt][i] = 1;
        for(int j = 1;j <= n;j++){
            if(graph[i][j]){
                d[tt][i] = max(d[tt][i],dp(j,tt)+1);
            }
        }
        return d[tt][i];
    }
    void print_ans(int i,int tt){
        printf("%d ",i);
        for(int j = 1;j <= n;j++){
            if(graph[i][j] && d[tt][i] == d[tt][j] + 1){
                print_ans(j,tt);
                break;
            }
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("input.in","r",stdin);
       // freopen("output.txt","w",stdout);
    #endif
        int t;
        scanf("%d",&t);
        while(t--){
        scanf("%d",&n);
        for(int i = 1;i <= n;i++){
            getchar();
            char ch;
            scanf("%c%d%d",&ch,&g[i].a,&g[i].b);
            //int fin = -1;
            for(int j = 1;j < i;j++){
                if(judge(i,j)){
                    graph[i][j] = 1;
                }
                if(judge(j,i)){
                    graph[j][i] = 1;
                }
            }
        }
        int ans = -1;
        int m;
        memset(d,0,sizeof(d));
        for(int i = 1;i <= n;i++){
            int tmp = dp(i,i);
            if(tmp > ans){
                m = i;
                ans = tmp;
            }
        }
        printf("%d
    ",ans);
        print_ans(m,m);
        }
        return 0;
    }
    View Code

    硬币问题

    有n种硬币,面值分别为v1,v2,v3……给定非负整数s问选用多少个硬币使面值恰好等于s?求出硬币数目最大值和最小值……

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <stack>
    #include <cctype>
    #include <string>
    #include <queue>
    #include <map>
    #include <set>
    
    using namespace std;
    
    const int INF = 0xffffff;
    const double esp = 10e-8;
    const double Pi = 4 * atan(1.0);
    const int maxn =  100+ 10;
    const long long mod =  1000000007;
    const int dr[] = {1,0,-1,0,-1,1,-1,1};
    const int dc[] = {0,1,0,-1,1,-1,-1,1};
    typedef long long LL;
    
    LL gac(LL a,LL b){
        return b?gac(b,a%b):a;
    }
    int V[maxn];
    int minv[maxn];
    int maxv[maxn];
    int d[maxn];
    int n;
    int dp(int i){
        if(d[i] != -1)
            return d[i];
        d[i] = -INF;
        for(int j = 1;j <= n;j++){
            if(i >= V[j]){
                d[i] = max(d[i],dp(i - V[j])+1);
            }
        }
        return d[i];
    }
    void print_ans(int * a,int s){
        for(int i = 1;i <= n;i++){
            if(s >= V[i] && a[s] == a[s -V[i] ]+1){
                printf("%d ",V[i]);
                print_ans(a,s-V[i]);
                break;
            }
        }
    }
    void print_Ans(int *a,int s){
        while(s){
            printf("%d ",a[s]);
            s -= a[s];
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("input.in","r",stdin);
       // freopen("output.txt","w",stdout);
    #endif
        while(~scanf("%d",&n)){
        int s;
        scanf("%d",&s);
        for(int i = 1;i <= n;i++){
            scanf("%d",&V[i]);
        }
        d[0] = 0;
        for(int i = 1;i <= s;i++)
            d[i] = -1;
        minv[0] = maxv[0] = 0;
        for(int i = 1;i <= s;i++){
            minv[i] = INF;
            maxv[i] = -INF;
        }
        int min_coin[maxn];
        int max_coin[maxn];
        for(int i = 1;i <= s;i++){
            for(int j = 1;j <= n;j++){
                if(i >= V[j]){
                    if(minv[i] > minv[i - V[j]]+1){
                        minv[i] = min(minv[i],minv[i-V[j] ] + 1);
                        min_coin[i] = V[j];
                    }
                    if(maxv[i] < maxv[i-V[j] ]+1){
                        maxv[i] = max(maxv[i],maxv[i -V[j] ]+1);
                        max_coin[i] = V[j];
                    }
                    minv[i] = min(minv[i],minv[i-V[j] ] + 1);
                    maxv[i] = max(maxv[i],maxv[i -V[j] ]+1);
                }
            }
        }
        print_Ans(min_coin,s);
        printf("
    ");
        print_Ans(max_coin,s);
        printf("
    ");
        printf("%d %d
    ",minv[s],maxv[s]);
        print_ans(minv,s);
        printf("
    ");
        print_ans(maxv,s);
        printf("
    ");
        int ans = dp(s) ;
        if(ans < -1){
            printf("no problem
    ");
        }
        else{
            printf("%d
    ",ans);
        }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    photoshop快捷键汇总
    div和css:行内元素和块元素的水平和垂直居中
    使块元素并排显示和清除浮动的方法
    javascript与DOM节点的结合使用
    导航+轮播图(手动)
    执行计划
    oracle存储过程
    oracle 常用语法
    Sqlserver数据库总结
    sqlserver sum 和count在关于进行统计时的区别
  • 原文地址:https://www.cnblogs.com/hanbinggan/p/4333004.html
Copyright © 2020-2023  润新知