動態規劃初步

CN_swords發表於2017-02-17

演算法競賽入門(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;
}
/*
4
1
3 2
4 10 1
4 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;
}
/*
4
1
3 2
4 10 1
4 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 5010
const 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;
}
/*
1
10
1 2
2 4
5 8
6 10
7 9
3 1
5 8
12 10
9 7
2 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 10010
const 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 7
1 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 10010
const 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 7
1 3 4
*/



相關文章