动态规划写法:
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <ctime>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
using namespace std;
const int MAX = 10010;
int N, M;
int C[MAX];
int DP[MAX] = {0};
int choice[MAX][110] = {0};
bool cmp(int a, int b)
{
return a > b;
}
int main()
{
scanf("%d %d", &N, &M);
for(int i=1; i<=N; i++) scanf("%d", &C[i]);
sort(C+1, C+N+1, cmp);//此处需要逆序,这样才能更新序列最小的路径
for(int i=1; i<=N; i++)
{
for(int v=M; v>=C[i]; v--)
{
if(DP[v] <= DP[v-C[i]] + C[i])
{
DP[v] = DP[v-C[i]] + C[i];
choice[i][v] = 1;
}
else choice[i][v] = 0;
}
}
if(DP[M] != M) printf("No Solution");
else
{
int v = M;
vector<int> path;//用path记录下路径信息,之后排序打印
for(int i=N; i>0 && v>0; i--)
{
if(choice[i][v])
{
path.push_back(C[i]);
v -= C[i];
}
}
sort(path.begin(), path.end());
for(int i=0; i<path.size(); i++)
{
if(i) printf(" ");
printf("%d", path[i]);
}
}
return 0;
}
DFS写法:(最后一个case超时)
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <ctime>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
using namespace std;
const int MAX = 1e4+10, INF = (1<<30)-1;
int C[MAX];
vector<int> S;
int N, M;
bool DFS(int i, int v)
{
if(v == M)
{
printf("%d", S[0]);
for(int j=1; j<S.size(); j++) printf(" %d", S[j]);
return true;
}
if(i >= N || v > M) return false;
S.push_back(C[i]);
if(DFS(i+1, v+C[i])) return true;//选择C【i】
S.pop_back();
return DFS(i+1, v);//不选择C[i]
}
int main()
{
scanf("%d %d", &N, &M);
for(int i=0; i<N; i++) scanf("%d", &C[i]);
sort(C, C+N);
if(!DFS(0, 0)) printf("No Solution");
return 0;
}