zoukankan      html  css  js  c++  java
  • DP_包括一些背包问题

    比赛链接

    C题

    一个二维背包问题

    //二维背包 
    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 1010;
    int  t[MAXN], a[MAXN], w[MAXN];
    int dp[MAXN][MAXN];
    int main () {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	int c;
    	cin >> c;
    	while(c--) {
    		int tt, aa;
    		cin >> tt >> aa;
    		int n;
    		cin >> n;
    		for(int i = 1; i <= n; ++i) {
    			cin >> t[i] >> a[i] >> w[i];
    		}
    		memset(dp, 0x3f3f3f3f, sizeof dp);
    		dp[0][0]= 0;
    		for(int i = 1; i <= n; ++i) {
    			for(int j = tt; j >= 0; --j) {
    				for(int k = aa; k >= 0; --k) {
    					int x = j + t[i] > tt ? tt: j + t[i];
    					int y = k + a[i] > aa ? aa : k + a[i];
    					dp[x][y] = min(dp[x][y], dp[j][k] + w[i]);
    //					cout << dp[x][y] << endl;
    				}
    			}
    		}
    		cout << dp[tt][aa] << endl;
    	}
    }
    /*
    1
    5 60
    5
    3 36 120
    10 25 129
    5 50 250
    1 45 130
    4 20 119
    */
    

     D题

    与昨天的DP题类似

    #include <bits/stdc++.h>
    using namespace std;
    int a[110][110];
    int dp[110][110];
    int main () {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	int T;
    	cin >> T;
    	while(T--) {
    		memset(a, 0, sizeof a);
    		memset(dp, 0, sizeof dp);
    		int h, w;
    		cin >> h >> w;
    		for(int i = 1; i <= h; ++i) {
    			for(int j = 1; j <= w; ++j) {
    				cin >> a[i][j];
    				if(i == 1) {
    					dp[i][j] = a[i][j];
    				}
    			}
    		}
    		for(int i = 2; i <= h; ++i) {
    			for(int j = 1; j <= w; ++j) {
    				dp[i][j] = max(max(dp[i - 1][j - 1], dp[i - 1][j]), dp[i - 1][j + 1]) + a[i][j];
    			}
    		}
    		int ans = -1;
    		for(int i = 1; i <= w; ++i) {
    			ans = max(ans, dp[h][i]);
    		}
    		cout << ans << endl;
    	}
    }
    

     E题

    跟上面的题类似

    #include <bits/stdc++.h>
    using namespace std;
    int a[110][110];
    int dp[110][110];
    int main () {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    //	int T;
    //	cin >> T;
    //	while(T--) {
    		memset(a, 0, sizeof a);
    		memset(dp, 0x3f3f3f3f, sizeof dp);
    		int h, w;
    		cin >> h >> w;
    		for(int i = 1; i <= h; ++i) {
    			for(int j = 1; j <= w; ++j) {
    				cin >> a[i][j];
    				if(i == 1) {
    					dp[i][j] = a[i][j];
    				}
    			}
    		}
    		for(int i = 2; i <= h; ++i) {
    			for(int j = 1; j <= w; ++j) {
    				dp[i][j] = min(min(dp[i - 1][j - 1], dp[i - 1][j]), dp[i - 1][j + 1]) + a[i][j];
    			}
    		}
    		int ans = 0x3f3f3f3f;
    		for(int i = 1; i <= w; ++i) {
    			ans = min(ans, dp[h][i]);
    		}
    		cout << ans << endl;
    //	}
    }
    

     F题

    典型的背包问题需要注意的是j从30开始取别从sum开始取,不然会被T

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
     
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int p[1100],w[1100],n;
            scanf("%d",&n);
            for(int i=0;i<n;i++)
                scanf("%d%d",&p[i],&w[i]);
            int dp[50];
            memset(dp,0,sizeof(dp));
            for(int i=0;i<n;i++)
                for(int j=30;j>=w[i];j--)
                    if(dp[j]<dp[j-w[i]]+p[i])
                        dp[j]=dp[j-w[i]]+p[i];
            int G,sum=0;
            scanf("%d",&G);
            while(G--)
            {
                int MW;
                scanf("%d",&MW);
                sum+=dp[MW];
            }
            printf("%d
    ",sum);
        }
      return 0;
    }
    

     G题

    easy,一维DP题

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll a[10010];
    ll dp[10010];
    int main (){
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	int T;
    	cin >> T;
    	int num = 1;
    	while(T--) {
    		memset(dp, 0, sizeof dp);
    		memset(a, 0, sizeof a);
    		int N;
    		cin >> N;
    		for(int i = 1; i <= N; ++i) {
    			cin >> a[i];
    		}
    		dp[1] = a[1];
    		for(int i = 2; i <= N; ++i) {	
    			dp[i] = max(dp[i - 1], dp[i - 2] + a[i]);
    		}
    		cout << "Case " << num++ << ": ";
    		cout << dp[N] << endl;
    	}
    }
    

     H题

    比较有灵性的DP题(背包问题)

    不过首先需要将素数打表,然后由背包问题求解

    //变形的背包问题 
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN = 5000;
    int pri[MAXN], vis[MAXN];
    int cnt = 0;
    int n = 1250;
    int dp[1300][20];
    void Pri() {
    	for(int i = 2; i <= n; ++i) {
    		if(!vis[i]) {
    			pri[++cnt] = i;
    		}
    		for(int j = 1; j <= cnt && i * pri[j] <= n; ++j) {
    			vis[i * pri[j]] = 1;
    			if(i % pri[j] == 0) {
    				break;
    			}
    		}
    	}
    }
    void solve() {
    	dp[0][0] = 1;
    	for(int i = 1; i <= cnt; ++i) {
    		for(int j = n; j >= pri[i]; --j) {
    			for(int k = 1; k <= 15; ++k) {
    				dp[j][k] += dp[j - pri[i]][k - 1];
    			}
    		}
    	}
    }
    int main (){
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	Pri();
    	solve(); 
    	ll n, k;
    	while(cin >> n >> k && (n + k)){
    		cout << dp[n][k] << endl;
    	}
    }
    
  • 相关阅读:
    Linux服务器之间进行文件目录映射/挂载 nfs rpcbind
    计算机英语Computer English
    收藏的网站
    java 通过sftp服务器上传下载删除文件
    收藏的博客
    MySQL练习题(简单查询)
    MySQL练习题
    Comparable接口和Comparator接口的使用和区别
    排序算法:快速排序
    排序算法:插入排序
  • 原文地址:https://www.cnblogs.com/lightac/p/13778609.html
Copyright © 2011-2022 走看看