标签: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