zoukankan      html  css  js  c++  java
  • URAL 1244 Gentlemen

    URAL 1244

    思路:dp,有点类似背包,不过不需要求最大价值,只要求方案数就可以了。

    状态:dp[i]表示和为i的方案数

    初始状态:dp[0]=1

    状态转移:dp[i]=∑dp[i-a[k]] (1<=k<=n)

    用一个pre[]数组来记录路径

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=1e5+5;
    int dp[N];
    int pre[N];
    int a[N];
    bool vis[N];
    vector<int>ans;
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0);
        int m,n;
        cin>>m;
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        if(m>1e5){
            cout<<0<<endl;
            return 0;
        }
        dp[0]=1;
        mem(pre,-1);
        for(int i=1;i<=n;i++){
            for(int j=m;j>=a[i];j--){
                if(dp[j-a[i]]){
                    dp[j]+=dp[j-a[i]];
                    if(pre[j]==-1)pre[j]=i;
                }
            }
        }
        if(dp[m]==0)cout<<0<<endl;
        else if(dp[m]==1){
            int t=pre[m];
            int sum=m;
            while(~t){
                vis[t]=true;
                m-=a[t];
                t=pre[m];
            }
            for(int i=1;i<=n;i++)if(!vis[i])ans.pb(i);
            for(int i=0;i<ans.size();i++){
                if(i==ans.size()-1)cout<<ans[i]<<endl;
                else cout<<ans[i]<<" ";
            }
        }
        else cout<<-1<<endl;
        return 0;
    }
  • 相关阅读:
    清北刷题班day3 morning
    [NOI1997] 积木游戏(dp)
    [NOI1999] 棋盘分割(推式子+dp)
    2017北京国庆刷题Day7 afternoon
    湖南集训day8
    湖南集训day7
    湖南集训day6
    湖南集训day5
    湖南集训day4
    湖南集训day3
  • 原文地址:https://www.cnblogs.com/widsom/p/8378652.html
Copyright © 2011-2022 走看看