dp练习

Posted babydragon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dp练习相关的知识,希望对你有一定的参考价值。

1013 Battle Over Cities

原来的图不一定连通,所以dfs统计连通块的时候要遍历所有的点。

pta总是有一些奇怪的边缘数据,

code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 1000+10;
vector<int> G[maxn];
int n, m, k;
int del[maxn];
bool vis[maxn];
int ans[maxn];
int no;

void dfs(int u, int p)
    vis[u] = true;
    for(int i=0; i<G[u].size(); i++)
        int v = G[u][i];
        if(v == p || v==no||vis[v]) continue;
        dfs(v, u);
    


int main()
    ios::sync_with_stdio(false);
    cin>>n>>m>>k;
    int u, v;
    for(int i=1; i<=m; i++)
        cin>>u>>v;
        G[u].push_back(v), G[v].push_back(u);
    
    for(int i=1; i<=k; i++)
        cin>>del[i];
        int tot = 0;
        no = del[i];
        cls(vis, 0);
        for(int j=1; j<=n; j++)
            if(j == del[i]) continue;
            if(!vis[j])
                tot++;
                dfs(j, -1);
            
        
        ans[i] = tot-1;
    
    for(int i=1; i<=k; i++) cout<<ans[i]<<endl;


    return 0;

unidirectional TSP

记录移动状态的dp问题,还算比较的常规

求一条路径最短的矩阵路径,若权重相同则要使行序的字典序最小。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 2000+10;
int num[15][105];
int dp[15][105];
int nex[15][105];
int n, m;

int main()
    ios::sync_with_stdio(false);
    while(~scanf("%d%d", &n, &m))
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                scanf("%d", &num[i][j]);
                dp[i][j] = inf;
            
        
        int ans = inf;

        for(int col=m; col>=1; col--)
            for(int row=1; row<=n; row++)
                if(col == m) dp[row][col] = num[row][col];
                else
                    int to[3] = row-1, row, row+1;
                    if(row == n) to[2] = 1;
                    if(row==1) to[0] = n;
                    sort(to, to+3);
                    for(int j=0; j<3; j++)
                        int temp = dp[to[j]][col+1]+num[row][col];
                        if(temp<dp[row][col])
                            dp[row][col] = temp;
                            nex[row][col] = to[j];
                        
                    
                
            
        
        int mi = inf;
        int first = -1;
        for(int i=1; i<=n; i++)
            if(dp[i][1]<mi)
                mi = dp[i][1];
                first = i;
            
        
        int j=1;
        for(int i=first; j<=m; j++)
            printf("%d%c", i, j==m?'\n':' ');
            i = nex[i][j];
        
        printf("%d\n", mi);
    

    return 0;

The lightning system

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 1000+10;
struct Node
    int v, k, c, l;
    bool operator < (const Node &b) const
        return v<b.v;
    
node[maxn];
int n;
int dp[maxn];
int pre[maxn];


int main()
    ios::sync_with_stdio(false);
    while(cin>>n&&n)

        for(int i=1; i<=n; i++)
            cin>>node[i].v>>node[i].k>>node[i].c>>node[i].l;
            //pre[i] = pre[i-1]+node[i].l;
        
        sort(node+1, node+1+n);
        pre[0] = 0;
        for(int i=1; i<=n; i++) dp[i] = inf, pre[i] = pre[i-1]+node[i].l;
        dp[1] = node[1].l*node[1].c+node[1].k;
        dp[0] = 0;
        for(int i=2; i<=n; i++)
            for(int j=0; j<i; j++)
                dp[i] = min(dp[i], dp[j]+(pre[i]-pre[j])*node[i].c+node[i].k);
            
        
        cout<<dp[n]<<endl;
    

    return 0;

jin ge jin qu(01背包)

条件有点唬人导致不敢做背包

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 180*50+678+10;
int dp[maxn];
int n;
int a[55];
int remain;

int main()
    ios::sync_with_stdio(false);
    int _;
    cin>>_;
    int kase = 1;
    while(_--)
        cin>>n>>remain;
        int tot = 0;
        for(int i=1; i<=n; i++) cin>>a[i], tot+=a[i];
        for(int i=1; i<=remain; i++) dp[i] = -1;
        dp[0] = 0;
        for(int i=1; i<=n; i++)
            for(int v=remain-1; v>=a[i]; v--)
                if(dp[v-a[i]]>=0)
                    dp[v] = max(dp[v], dp[v-a[i]]+1);
                
            
        
        int mx = -1;
        int last = -1;
        for(int i=remain-1; i>=0; i--)
            if(mx<dp[i])
                mx = dp[i];
                last = i;
            
        
        cout<<"Case "<<kase++<<": "<<mx+1<<" "<<last+678<<endl;


    

    return 0;

矩阵的链乘(区间dp)

将问题转化为n-1矩阵的相乘

时间复杂度是\(O(n^3)\)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 100+10;
int a[maxn];
int dp[maxn][maxn];
int n;
struct Matrix
    int x, y;
node[maxn];

int main()
    ios::sync_with_stdio(false);
    while(cin>>n)
        for(int i=1; i<=n; i++) cin>>a[i];
        node[1].x=a[1] ,node[1].y=a[2];
        for(int i=2; i<=n-1; i++)
            node[i].x=a[i], node[i].y=a[i+1];
        
        cls(dp, 0x3f);
        for(int i=1; i<=n-2; i++)
            dp[i][i+1] = node[i].x*node[i].y*node[i+1].y;
        
        for(int i=1; i<=n-1; i++) dp[i][i] = 0;
        for(int l=3; l<=n-1; l++)
            for(int i=1; i<=n-l+1; i++)
                int j=i+l-1;
                for(int k=i; k<=j; k++)
                    //cout<<i<<" "<<k<<" "<<j<<endl;
                    if(dp[i][k]!=inf&&dp[k+1][j]!=inf)
                        dp[i][j] = min(dp[i][j], dp[i][k]+dp[k+1][j]+node[i].x*node[k].y*node[j].y);
                
            
        
        //cout<<dp[1][4]<<endl;
        cout<<dp[1][n-1]<<endl;
    

    return 0;

以上是关于dp练习的主要内容,如果未能解决你的问题,请参考以下文章

DP练习

2023-05-04 线性DP_力扣练习

状压dp小练习(LuoGu)

dp的一些练习

决策单调性优化dp 专题练习

dp专题练习