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\n",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("\n");

    print_Ans(max_coin,s);

    printf("\n");

    printf("%d %d\n",minv[s],maxv[s]);

    print_ans(minv,s);

    printf("\n");

    print_ans(maxv,s);

    printf("\n");

    int ans = dp(s) ;

    if(ans < -1){

        printf("no problem\n");

    }

    else{

        printf("%d\n",ans);

    }

    }

    return 0;

}
View Code

 

你可能感兴趣的:(动态规划)