标签:就是 algorithm 移除 lib ret cout news clu pre
第一行输入一个正整数n(n ≤ 1000) 第二行为n个数正整数xi(xi ≤ 1000)
输出可以产生的幸运的袋子数
3 1 1 1
2
思路:好像并没有太好的方法,深度优先搜索加上适当的剪枝做出的这道题目。。。还有一点就是避免重复。
#include<iostream> #include<algorithm> #include<vector> using namespace std; int res = 0;//全局变量返回值
void dfs(int sum, int mult, int index, bool flag, vector<int> & num){//flag是用来标记与前一个数字重复时前一个数字是否被计入。若前一个被计入则当前节点可计入,也可不计入;若前一节点未被计入则当前节点也不计入。(为了防止重复。) if(index == num.size()) return; //边界处理 int newsum = sum+num[index]; int newmult = mult*num[index]; if(index == 0){ //第一个数的时候特殊处理,若最小的数不是1直接返回0 if(num[0] == 1) { dfs(newsum, newmult,index+1,true,num); dfs(sum, mult,index+1,false,num); }else{ return ; } }else{ if(num[index] == num[index-1]){//与前一节点重复 if(flag){//true的时候当前节点分两种讨论 if(newsum>newmult) {//当前节点加入是否符合要求,若符合则继续,否则直接退出(剪枝) res+=1; dfs(newsum, newmult,index+1,true,num); } dfs(sum, mult,index+1,false,num); }else{//重复且前一节点未计入,则当前也不计入 dfs(sum, mult,index+1,false,num); } }else{ if(newsum>newmult) { res+=1; dfs(newsum, newmult,index+1,true,num); } dfs(sum, mult,index+1,false,num); } } } int main(){ int counts = 0,temp; vector<int> nums; cin>>counts; for(int i=0;i<counts;++i){ cin>>temp; nums.push_back(temp); } sort(nums.begin(),nums.end());//排序有利于后续剪枝 dfs(0,1,0,false,nums); cout<<res; return 0; }
看了一下网上其他同学的答案,总体思路还是相似的,但他们的好像更简洁一点。。。这里贴上其中一位的代码:
对重复元素的排除方法不一样。
#include <iostream> #include <stdlib.h> using namespace std; int n; int nums[1000]; int cmp(const void * a, const void * b) { return *(int*)a - *(int*)b; } // 思路:DFS生成全组合,同时注意剪枝、避免重复组合 int findall(int nums[], int index, long sum, long multi) { int count = 0; for(int i=index; i<n; i++) { sum += nums[i]; multi *= nums[i]; if(sum > multi) count += 1 + findall(nums, i+1, sum, multi); else if(nums[i] == 1) count += findall(nums, i+1, sum, multi); else break; sum -= nums[i]; multi /= nums[i]; // 跳过相等的元素,避免重复组合 while(i<n-1 && nums[i]==nums[i+1]) i++; } return count; } int main(int argc, char* argv[]) { while(cin >> n) { for(int i=0; i<n; i++) cin >> nums[i]; // 从小到大排序 qsort(nums, n, sizeof(int), cmp); cout << findall(nums, 0, 0, 1) << endl; } return 0; }
标签:就是 algorithm 移除 lib ret cout news clu pre
原文地址:https://www.cnblogs.com/J1ac/p/9446011.html