zoukankan      html  css  js  c++  java
  • CF687C Solution

    题目链接

    题解

    数据范围可知是一道dp题。思考时发现,在转移时需要上一个状态能得出的价值,但存储每个状态的所有价值并不可行。这时注意到可得价值\(\le k\)\(k\le 500\),可以用可行性dp判断每一个价值。

    状态:\(dp[i][j][p]\)表示前\(i\)个数中选出和为\(j\)的数是/否(0/1)可以得出价值\(p\)

    初始值:\(dp[0][0][0]=1\)

    转移方程:

    \[dp[i][j][p]|=dp[i-1][j][p]\\ dp[i][j][p]|=dp[i-1][j-c_i][p]\quad (j\ge c_i)\\ dp[i][j][p]|=dp[i-1][j-c_i][p-c_i]\quad (j\ge c_i,p\ge c_i)\\ (1\le i\le n,0\le j\le k,0\le p\le j) \]

    第1行为不选\(c_i\)的情况。第2行为选\(c_i\)但不用其凑价值\(p\)的情况。第3行为选\(c_i\)并用其凑价值\(p\)的情况。

    答案:\(q=\sum\limits_{i=0}^k dp[n][k][i]\)\(values=i(0\le i\le k,dp[n][k][i]=1)\)

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=501;
    int c[N];
    bool dp[N][N][N];
    int main()
    {
    	int n,k,ans=0;
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++) scanf("%d",&c[i]);
    	dp[0][0][0]=1;
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=0;j<=k;j++)
    		{
    			for(int p=0;p<=j;p++)
    			{
    				dp[i][j][p]|=dp[i-1][j][p];
    				if(j>=c[i]) dp[i][j][p]|=dp[i-1][j-c[i]][p];
    				if(j>=c[i] && p>=c[i]) dp[i][j][p]|=dp[i-1][j-c[i]][p-c[i]];
    			}
    		}
    	}
    	for(int i=0;i<=k;i++) ans+=dp[n][k][i];
    	printf("%d\n",ans);
    	for(int i=0;i<=k;i++)
    		if(dp[n][k][i]) printf("%d ",i);
    	return 0;
    }
    
  • 相关阅读:
    第一章—v-text和v-html
    第一章—v-for
    第一章—v-show
    react_9
    【软件工程】
    【软件工程】网页设计基础 第一章
    【软件工程】psp四则运算
    【python】网络爬虫与信息提取
    【python】数据库学习笔记,设计自己的大学排名
    【python】用python玩微信跳一跳小游戏
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14388359.html
Copyright © 2011-2022 走看看