DP问题

作者: Vincy_ivy | 来源:发表于2019-05-22 21:47 被阅读0次

多重部分和问题

模板题


代码

#include<iostream>
using namespace std;
#define Max_K 100000
int dp[Max_N+1][Max_K+1];
int a[Max_N];
int m[Max_N];
int n,K;
 
void solve()
{
    dp[0][0]=0;
    for(int j=1;j<=K;j++)
      dp[0][j]=-1;          //用前0种数凑成和不为0的,肯定不行
  
  //dp[i][j] 用前i种数(下标0~i-1)在能凑成和为j时,第i个数(下标为i-1)
  //最多可以剩余多少个,-1表示前i种数凑不成和为j 
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=K;j++)
        {
            if(dp[i-1][j]>=0)     
            //如果前i-1种数就能凑成和为j,那么第i个数a[i-1]可以一个都不用,全部剩下来
                dp[i][j]=m[i-1];
            else             //前i-1种数凑不成和为j,那么就用第i个数a[i-1]尝试凑
            {
    //如果要凑的和j小于a[i-1],那么肯定凑不成j   ------   j<a[i-1]
    //无法用前i个数凑不成和j-a[i-1],那么无论再加不加上一个数a[i-1],都凑不成和j  -----dp[i][j-a[i-1]<0
    //如果在用前i个数能凑成和j-a[i-1],但是这时候a[i-1]数用完了,那么也是凑不成的 ------dp[i][j-a[i-1]=0
                if(j<a[i-1] || dp[i][j-a[i-1]]<=0)
                 dp[i][j]=-1;
                else
    //在前i种数能凑成和j-a[i-1]并且数a[i-1]还有剩余,那么是能凑成的,再用掉一个a[i-1],所以个数减一 
                 dp[i][j]=dp[i][j-a[i-1]]-1; 
            } 
            //cout<<"dp["<<i<<"]["<<j<<"]:"<<dp[i][j]<<endl;   //测试使用 
        }
    } 
      //dp[n][K]>=0表明前n个数(a[0]~a[n-1])在凑成和为K时,数a[i-1]不剩余或者还有剩余,
    //但是不管剩余还是不剩余,都是能凑成和为j 
    if(dp[n][K]>=0) cout<<"Yes\n";
    else cout<<"No\n";

    return ;
}

int main()
{
    cin>>n>>K;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }

    for(int i=0;i<n;i++)
    {
        cin>>m[i];
    }
    solve();
}

Holding Bin-Laden Captive!

这道题的数组得开的很小心,太小了会wa 太大了会MLE
定义dp[i][j]为前i种组成j的时候第i中数剩余多少

#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
int dp[5][15000];
int a[4]={0,1,2,5};
int m[5];
int n,K=15000;

int main()
{
    while(cin>>m[1]>>m[2]>>m[3]&&(m[1]!=0||m[2]!=0||m[3]!=0)){
        memset(dp,-1,sizeof(dp));
        dp[0][0]=0;
        for(int i=1;i<=3;i++)
            for(int j=0;j<=K;j++){
                if(dp[i-1][j]>=0)
                    dp[i][j]=m[i];
                else if(a[i]>j||dp[i][j-a[i]]<=0){
                    dp[i][j]=-1;
                }else{
                    dp[i][j]=dp[i][j-a[i]]-1;
                }
            }
        int res;
        for(int j=0;j<=K;j++){
            if(dp[3][j]==-1)
            {
                res=j;
                break;
            }
        }
        cout<<res<<endl;
    }
    return 0;
}

相关文章

  • LeetCode之Unique Paths(Kotlin)

    问题: 方法:经典的动态规划问题,dp[i][j] = dp[i-1][j] + dp[i][j-1],然后dp遍...

  • DP问题

    DP问题常用来解决最优解能由子最优解构成的问题。 核心问题就是我是谁,我从哪里来,我到哪里去。 我是谁 就是代表现...

  • DP问题

    多重部分和问题 模板题 代码 Holding Bin-Laden Captive!这道题的数组得开的很小心,太小了...

  • AcWing 285. 没有上司的舞会

    AcWing 285. 没有上司的舞会 树形dp 从小偷系列问题演变过来的树形dp问题

  • Leetcode 【39、40、77】

    问题描述:【DFS、DP】39. Combination Sum 解题思路: 这道题和 Leetcode 【DP】...

  • 偶遇DP问题

    今天偶然遇到一个买卖股票最佳时机(best-time-to-buy-and-sell-stock)的问题。这个问题...

  • dp经典问题

    1. 最长子序列问题 最长上升不连续子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入:...

  • dp背包问题

    1、说明 leetcode做了几十道动态规划的题目,大部分都是参考别人的解法进行解答,对动态规划的理解还是不到位,...

  • 377. Combination Sum IV [Medium]

    377. Combination Sum IV 可以分解成子问题,且子问题有重复,很明显DP问题DP是一个targ...

  • 2022-02-19 动态规划高频题专题【1】

    动态规划基本类型 dp基础 背包问题 打家劫舍 股票问题 子序列问题 进阶动态规划 深入理解动态规划过程 定义dp...

网友评论

      本文标题:DP问题

      本文链接:https://www.haomeiwen.com/subject/ifioaqtx.html