687C

dp

以前做过 忘了。

想破脑袋不知道怎么设状态

dp[i][j][k]表示选到第i个硬币,当前和为j,能否弄出k

dp[i][j][k]|=dp[i-1][j][k]|dp[i-1][j][k-c[i]]|dp[i-1][j-c[i]][k-c[i]]

如果发现状态不行,就试着多加一维,也许就能搞定

#include<bits/stdc++.h>
using namespace std;
const int N = 510;
int n, k, pre;
int dp[2][N][N], c[N];
vector<int> ans;
int main()
{
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n;++i) scanf("%d", &c[i]);
    dp[pre][0][0] = 1;
    for(int x = 1; x <= n; ++x)
    {
        pre ^= 1;
        for(int i = 0; i <= k; ++i)
            for(int j = 0; j <= k; ++j)    
            {
                dp[pre][i][j] = dp[pre ^ 1][i][j];    
                if(i - c[x] >= 0)
                {    
                    dp[pre][i][j] |= dp[pre ^ 1][i - c[x]][j];
                    if(j - c[x] >= 0)
                        dp[pre][i][j] |= dp[pre ^ 1][i - c[x]][j - c[x]];
                }
            }
    }
    for(int i = 0; i <= k; ++i) if(dp[pre][k][i])
        ans.push_back(i);
    printf("%d\n", ans.size());
    sort(ans.begin(), ans.end());
    for(int i = 0; i < ans.size(); ++i) printf("%d ", ans[i]); 
    return 0;
}
View Code

 

posted @ 2017-07-15 16:51  19992147  阅读(173)  评论(0编辑  收藏  举报