动态规划初步

来源:互联网 发布:mac brew lnmp 编辑:程序博客网 时间:2024/06/05 16:24

算法竞赛入门(LJR) ,请结合此书观看

动态规划初步

/*算法竞赛入门 LRJ 数字三角形时间: 2017/02/17递推*/#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>#include <queue>using namespace std;const int INF = 0x3f3f3f3f;const int N = 110;double esp = 1e-5;int dp[N];int a[N][N];int main(){    int n;    scanf("%d",&n);    for(int i = 0; i < n; i++)        for(int j = 0; j <= i; j++)            scanf("%d",&a[i][j]);    memset(dp,0,sizeof(dp));    for(int i = n-1; i >= 0; i--)    {        for(int j = 0; j <= i; j++)            dp[j] = a[i][j] + max(dp[j],dp[j+1]);    }    printf("%d\n",dp[0]);    return 0;}/*413 24 10 14 3 2 20*/


/*算法竞赛入门 LRJ 数字三角形时间: 2017/02/17记忆化搜索*/#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>#include <queue>using namespace std;const int INF = 0x3f3f3f3f;const int N = 110;int dp[N][N];int a[N][N];int n;int slove(int i,int j){    if(dp[i][j] >= 0)   return dp[i][j];    return dp[i][j] = a[i][j] + (i==n-1 ? 0:max(slove(i+1,j),slove(i+1,j+1)));}int main(){    scanf("%d",&n);    for(int i = 0; i < n; i++)        for(int j = 0; j <= i; j++)            scanf("%d",&a[i][j]);    memset(dp,0xff,sizeof(dp));    printf("%d\n",slove(0,0));    for(int i = 0 ; i < n; i++)    {        for(int j = 0; j <= i; j++)            printf("%d ",dp[i][j]);        puts("");    }    return 0;}/*413 24 10 14 3 2 20*/


/*DAG模型 嵌套矩形问题时间: 2017/02/18记忆化搜索*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <vector>#include <map>using namespace std;#define LL long long#define INF 0x3f3f3f3f#define PI acos(-1.0)#define E 2.71828#define MOD 1000000007#define N 1010#define M 5010const double eps=1e-8;struct asd{    int x,y;} a[N];vector<int> mp[N];int dp[N];  //表示从i结点出发的最长路长度(即嵌套矩阵的最多个数)bool pan(asd a, asd b){    if(max(a.x,a.y) < max(b.x,b.y) && min(a.x,a.y) < min(b.x,b.y))        return true;    return false;}int solve(int i){    int &ans = dp[i];    if(ans > 0) return ans;    if(mp[i].empty())   ans = 1;    for(vector<int>::const_iterator k = mp[i].begin(); k != mp[i].end(); k++)    {        int j = *k;        ans = max(ans,solve(j)+1);    }    return ans;}void print_ans(int i){    printf("%d ",i);    int f;    if(mp[i].empty())   return ;    for(vector<int>::const_iterator k = mp[i].begin(); k != mp[i].end(); k++)    {        int j = *k;        if(dp[j]+1 == dp[i])            f = min(f,j);    }    print_ans(f);}int main(){    int T;    scanf("%d",&T);    while(T--)    {        int n;        scanf("%d",&n);        for(int i = 0; i < n; i++)        {            scanf("%d%d",&a[i].x,&a[i].y);            mp[i].clear();        }        for(int i = 0; i < n; i++)        {            for(int j = 0; j < n; j++)            {                if(pan(a[i],a[j]))                    mp[i].push_back(j);            }        }        memset(dp,0,sizeof(dp));        int res = 0,id;        for(int i = 0; i < n; i++)        {            if(res < solve(i))            {                res = solve(i);                id = i;            }        }        printf("%d\n",res);        print_ans(id);    }    return 0;}/*1101 22 45 86 107 93 15 812 109 72 2*/

/*DAG模型 硬币问题时间: 2017/02/18递推(完全背包)*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <vector>#include <map>using namespace std;#define LL long long#define INF 0x3f3f3f3f#define PI acos(-1.0)#define E 2.71828#define MOD 1000000007#define N 110#define M 10010const double eps=1e-8;int a[N],dpmax[M],dpmin[M];int main(){    int n,S;    scanf("%d%d",&n,&S);    for(int i = 0; i < n; i++)        scanf("%d",&a[i]);    dpmax[0] = dpmin[0] = 0;    for(int i = 1; i <= S; i++)    {        dpmax[i] = -INF;        dpmin[i] = INF;    }    for(int i = 0; i < n; i++)    {        for(int j = a[i]; j <= S; j++)        {            dpmax[j] = max(dpmax[j],dpmax[j-a[i]]+1);            dpmin[j] = min(dpmin[j],dpmin[j-a[i]]+1);        }    }    printf("%d %d\n",dpmax[S],dpmin[S]);    return 0;}/*3 71 3 4*/

/*DAG模型 硬币问题时间: 2017/02/18记忆化搜索*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <vector>#include <map>using namespace std;#define LL long long#define INF 0x3f3f3f3f#define PI acos(-1.0)#define E 2.71828#define MOD 1000000007#define N 110#define M 10010const double eps=1e-8;int a[N],vis[N],dpmax[M],dpmin[M];int n,S;int solve(int s){    int &ans = dpmax[s];    if(vis[s]) return ans;    vis[s] = 1;    ans = -INF;    for(int i = 0; i < n; i++)        if(a[i] <= s)            ans = max(ans,solve(s-a[i])+1);    return ans;}int solve2(int s){    int &ans = dpmin[s];    if(vis[s]) return ans;    vis[s] = 1;    ans = INF;    for(int i = 0; i < n; i++)        if(a[i] <= s)            ans = min(ans,solve2(s-a[i])+1);    return ans;}void print_ans(int s){    for(int i = 0; i < n; i++)        if(s >= a[i] && dpmax[s] == dpmax[s-a[i]]+1)        {            printf("%d ",a[i]);            print_ans(s-a[i]);            break;        }}int main(){    scanf("%d%d",&n,&S);    for(int i = 0; i < n; i++)        scanf("%d",&a[i]);    dpmax[0] = dpmin[0] = 0;    memset(vis,0,sizeof(vis));    vis[0] = 1;    solve(S);    memset(vis,0,sizeof(vis));    vis[0] = 1;    solve2(S);    printf("%d %d\n",dpmax[S],dpmin[S]);    //打印字典序最小方案    print_ans(S);    return 0;}/*3 71 3 4*/


0 0