标签:pch 背包问题 stl容器 main 示例 iss algo 类型 bug
#include <iostream> #include <algorithm> #include <vector> using namespace std; int main(){ vector<int> str; for(int i=1; i<5; i++) str.push_back(i); //这里我是默认的将输入数组变成了升序排序,如果要求全排列必须重新排序。
sort(str.begin(), str.end()); while(next_permutation(str.begin(), str.end())){ for(int i=0; i<4; i++) cout<<str[i]; cout<<endl; } }
class Solution { public: void nextPermutation(vector<int> &num) { int size = num.size(); if (size < 2) return ; int i, j; for (i=size-2; i>=0; --i)//这个是从后往前找到相邻的两个数,其中第i个数小于第i+1个数 if (num[i] < num[i+1]) break; for (j=size-1; j>i; --j)//这个是从后找到一个大于第i个数的j if (num[j] > num[i]) break; if (i>=0) swap(num[i], num[j]);//交换第i个数和第j个数 reverse(num.begin()+i+1, num.end());//再将第i+1后面的所有数字进行翻转,就形成了下一个序列 } };
class Solution { public: bool nextPermutation(vector<int> &num) { int size = num.size(); if (size < 2) return false; int i, j; for (i=size-2; i>=0; --i)//这个是从后往前找到相邻的两个数,其中第i个数小于第i+1个数 if (num[i] < num[i+1]) break; for (j=size-1; j>i; --j)//这个是从后找到一个大于第i个数的j if (num[j] > num[i]) break; if (i>=0) swap(num[i], num[j]);//交换第i个数和第j个数 reverse(num.begin()+i+1, num.end());//再将第i+1后面的所有数字进行翻转,就形成了下一个序列 return i>=0; } vector<vector<int> > permute(vector<int> &num) { vector<vector<int> > res; sort(num.begin(), num.end());//这里是求全排列,所以我们需要将数组重新排序才能得出 do{ res.push_back(num); }while(nextPermutation(num)); return res; } };
#include<iostream> using namespace std; #include<assert.h> #include <stdio.h> void Permutation(char* pStr, char* pBegin) { assert(pStr && pBegin); if(*pBegin == ‘\0‘) printf("%s\n",pStr); else { for(char* pCh = pBegin; *pCh != ‘\0‘; pCh++) { swap(*pBegin,*pCh); Permutation(pStr, pBegin+1); swap(*pBegin,*pCh); } } } int main(void) { char str[] = "abc"; Permutation(str,str); return 0; }
#include<iostream> using namespace std; #include<assert.h> //在[nBegin,nEnd)区间中是否有字符与下标为pEnd的字符相等 bool IsSwap(char* pBegin , char* pEnd) { char *p; for(p = pBegin ; p < pEnd ; p++) { if(*p == *pEnd) return false; } return true; } void Permutation(char* pStr , char *pBegin) { assert(pStr); if(*pBegin == ‘\0‘) { static int num = 1; //局部静态变量,用来统计全排列的个数 printf("第%d个排列\t%s\n",num++,pStr); } else { for(char *pCh = pBegin; *pCh != ‘\0‘; pCh++) //第pBegin个数分别与它后面的数字交换就能得到新的排列 { if(IsSwap(pBegin , pCh)) { swap(*pBegin , *pCh); Permutation(pStr , pBegin + 1); swap(*pBegin , *pCh); } } } } int main(void) { char str[] = "baa"; Permutation(str , str); return 0; }
1、问题其实本质上就是0/1背包问题,对于每一个n,我们采用贪婪策略,先考察是否取n,如果取n,那么子问题就变成了find(n-1,m-n),而如果舍弃n,子问题则为find(n-1,m)。
2、那么,如何制定解的判定策略?我们知道,递归需要边界条件,而针对背包问题,边界条件只有两种,如果n<1或者m<1,那么便相当于“溢出”,无法combo出m,而另一种可能就是在剩余的n个里恰好满足m==n,即此时 背包刚好填充满,输出一组解单元。除此之外,再无其他。
注:我们设置flag背包,用来标注对应的n+1是否被选中,1表示被选中,0则表示未选中,每当满足m==n时,则输出一组解。程序容易产生逻辑bug的地方在于length的使用(读者可以思考一下为何需要全局变量length,而不是直接使用n来代替for循环)。
#include <stdio.h> #include <stdlib.h> #include <string.h> int length; void findCombination(int n,int m,int *flag) { if(n < 1 || m < 1) return; if(n > m) n = m; if(n == m) { flag[n-1] = 1; for(int i=0;i<length;i++) { if(flag[i] == 1) printf("%d\t",i+1); } printf("\n"); flag[n-1] = 0; } flag[n-1] = 1; findCombination(n-1,m-n,flag); flag[n-1] = 0; findCombination(n-1,m,flag); } int main() { int n, m; scanf("%d%d",&n,&m); length = n; int *flag = (int*)malloc(sizeof(int)*length); findCombination(n,m,flag); free(flag); return 0; }
标签:pch 背包问题 stl容器 main 示例 iss algo 类型 bug
原文地址:http://www.cnblogs.com/Kobe10/p/6344178.html