题目大意

  给出一个整数集合$A$,总数$N$,规定一个整数序列$\{a_n\}, \forall i, a_i\in A$满足条件:存在一个正整数序列$\{k_n\}$,使得$\sum_{i=1}^n a_i k_i = S$。求$n$最小值且字典序最小的$a_i$。

题解

错误解法

  令$f(j)$表示使得$\sum_{i=1}^m a_i k_i = j$的最小的$m$的值,令$i$为第几个$A$中的整数,则刷表递推式方式为UpdateMin$(f(j+A_i k),f(j)+1)$。这时我想,如果把$A$中的元素从小到大排序,只有能将以后的状态更新成最小时才更新答案,那么记录到的决策必然就是字典序最小的了。这样就错了,因为如果组成$j_1+K_1 A_{i_1}=j_2+K_2A_{i_2}=S$,$i_1 < i_2$,我们无法证明组成$j_1$的元素的字典序就比$j_2$的小。反例很难容易得出。

正确解法

  对每个$n$枚举$a_i$为$N$内的组合,然后用完全背包判断选择的组合是否满足条件即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; const int MAX_OBJ = 150, MAX_V = 21000;
int TotObj, TotV;
int Vs[MAX_OBJ];
vector<int> Ans; bool DP(int *_vs)
{
static bool f[MAX_V], vis[MAX_V];
memset(f, false, sizeof(f));
f[0] = true;
for (int i = 1; i <= TotObj; i++)
{
if (!_vs[i])
continue;
memset(vis, false, sizeof(vis));
for (int j = 0; j <= TotV; j++)
{
if (f[j] && !vis[j])
{
for (int k = 1; k <= (TotV - j) / _vs[i]; k++)
{
f[j + k * _vs[i]] = true;
}
}
}
}
return f[TotV];
} void JudgeAns(vector<int>& chosen)
{
static int _vs[MAX_OBJ];
memset(_vs, 0, sizeof(_vs));
for (unsigned int i = 0; i < chosen.size(); i++)
_vs[chosen[i]] = Vs[chosen[i]];
if (DP(_vs))
Ans = chosen;
} void Comb(vector<int>& chosen, int n, int m, int begin, void (*doSth)(vector<int>&))
{
if (n - begin + 1 < m - chosen.size())
return;
if (chosen.size() == m)
{
doSth(chosen);
return;
}
for (int i = begin; i <= n; i++)
{
if (Ans.size())
return;
chosen.push_back(i);
Comb(chosen, n, m, i + 1, doSth);
chosen.pop_back();
}
} int main()
{
scanf("%d%d", &TotV, &TotObj);
for (int i = 1; i <= TotObj; i++)
scanf("%d", Vs + i);
sort(Vs + 1, Vs + TotObj);
vector<int> chosen;
for (int i = 1; i <= TotObj; i++)
{
Comb(chosen, TotObj, i, 1, JudgeAns);
if (Ans.size())
break;
}
printf("%d ", (int)Ans.size());
for (unsigned int i = 0; i < Ans.size(); i++)
printf("%d ", Vs[Ans[i]]);
printf("\n");
return 0;
}

  

最新文章

  1. MySQL 5.7:非结构化数据存储的新选择
  2. python基础(四)运算
  3. 在ubuntu上搭建开发环境6---安装和使用vim及其插件(Pathogen和NERDTree)
  4. HDU4057 Rescue the Rabbit(AC自动机+状压DP)
  5. iOS开发 autoResizingMask使用
  6. HTML中Id和Name的区别
  7. iOS 8 新特性
  8. 测试redis+keepalived实现简单的主备切换【转载】
  9. DOS命令(一)
  10. BZOJ1299: [LLH邀请赛]巧克力棒(Nim游戏)
  11. day03 基本数据类型
  12. Check failed: mdb_status == 0 (13 vs. 0) Permission denied
  13. 冒泡排序之python
  14. android-------高德地图两点路线和多个点路线绘制
  15. gtk+学习笔记(六)
  16. logstash5.5.0同步sql server数据
  17. 【刷题】BZOJ 4950 [Wf2017]Mission Improbable
  18. Quartz使用总结(转发:http://www.cnblogs.com/drift-ice/p/3817269.html)
  19. JAVA学习笔记----【转】 java.toString() ,(String),String.valueOf的区别
  20. clipRect 介绍

热门文章

  1. 6.11 将分割数据转换为多值IN列表
  2. codeforces_456C_dp
  3. 梦想CAD控件网页版标注样式
  4. 梦想CAD控件关于id与handle问题
  5. Oracle 11g 字符集修改
  6. 【maven】Description Resource Path Location Type An error occurred while filtering resources TESTVIDEO line
  7. 类模板成员函数默认值问题:an out-of-line definition of a member of a class template cannot have default arguments
  8. [Luogu] P4366 [Code+#4]最短路
  9. UVA - 1623 Enter The Dragon(贪心)
  10. UVA - 10410 Tree Reconstruction(栈处理递归)