码迷,mamicode.com
首页 > 其他好文 > 详细

DAG上的动态规划

时间:2015-03-12 18:43:06      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:

嵌套矩形问题(最长路及其字典序)
有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

 

DAG上的动态规划

标签:

原文地址:http://www.cnblogs.com/hanbinggan/p/4333004.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!