第二章
设计算法求解整数的划分问题
#include <stdio.h>
const int N= 1000 ;
int n;
int cnt= 0 ;
int dfs ( int n, int m) {
if ( n== 1 || m== 1 ) {
return 1 ;
}
if ( n> m) {
return dfs ( n- m, m) + dfs ( n, m- 1 ) ;
}
if ( n> m) {
return dfs ( n, n) ;
}
return dfs ( n, n- 1 ) + 1 ;
}
int main ( ) {
scanf ( "%d" , & n) ;
print ( "%d" , dfs ( n, n) ) ;
return 0
}
有重复元素的排列问题
#include <stdio.h>
const int N= 1000 ;
int n;
int cnt= 0 ;
char arr[ N] , state[ N] ;
int used[ N] = { 0 } ;
void dfs ( char ch[ ] , int n, char b[ ] , int p) {
if ( p== n) {
printf ( "%s\n" , b) ;
cnt++ ;
return ;
}
for ( int i= 0 ; i< n; i++ ) {
if ( i> 0 && ch[ i] == ch[ i- 1 ] && ! used[ i- 1 ] ) continue ;
if ( ! used[ i] ) {
used[ i] = 1 ;
b[ p] = ch[ i] ;
dfs ( ch, n, b, p+ 1 ) ;
used[ i] = 0 ;
}
}
}
int main ( ) {
scanf ( "%d" , & n) ;
scanf ( "%s" , arr) ;
char b[ n+ 1 ] = "" ;
dfs ( arr, n, b, 0 ) ;
printf ( "%d" , cnt) ;
}
棋盘覆盖问题
#include <stdio.h>
#include <math.h>
int k;
int x, y;
const int max= 1 << 10 ;
int board[ max] [ max] ;
int number;
void chessboard ( int row, int column, int x, int y, int siz) {
if ( siz== 1 ) {
return ;
}
int s= siz/ 2 ;
int t= ++ number;
int centerRow= row+ s;
int centerColumn= column+ s;
if ( x< centerRow&& y< centerColumn) {
chessboard ( row, column, x, y, s) ;
} else {
board[ centerRow- 1 ] [ centerColumn- 1 ] = t;
chessboard ( row, column, centerRow- 1 , centerColumn- 1 ) ;
}
if ( x < centerRow && y >= centerColumn) {
chessboard ( row, centerColumn, x, y, s) ;
} else {
board[ centerRow - 1 ] [ centerColumn] = t;
chessboard ( row, centerColumn, centerRow - 1 , centerColumn, s) ;
}
if ( x >= centerRow && y < centerColumn) {
chessboard ( centerRow, column, x, y, s) ;
} else {
board[ centerRow] [ centerColumn - 1 ] = t;
chessboard ( centerRow, column, centerRow, centerColumn - 1 , s) ;
}
if ( x >= centerRow && y >= centerColumn) {
chessboard ( centerRow, centerColumn, x, y, s) ;
} else {
board[ centerRow] [ centerColumn] = t;
chessboard ( centerRow, centerColumn, centerRow, centerColumn, s) ;
}
}
int main ( ) {
scanf ( "%d" , & k) ;
scanf ( "%d%d" , & x, & y) ;
int siz= pow ( 2 , k) ;
board[ x] [ y] = 0 ;
number= 0 ;
chessboard ( 0 , 0 , x, y, siz) ;
for ( int i= 0 ; i< siz; i++ ) {
for ( int j= 0 ; j< siz; j++ ) {
if ( j== siz- 1 ) {
printf ( "%d" , board[ i] [ j] ) ;
}
else {
printf ( "%-4d" , board[ i] [ j] ) ;
}
}
printf ( "\n" ) ;
}
return 0 ;
}
全排列
#include <stdio.h>
#include <stdlib.h>
int n= 0 ;
void swap ( int * a, int * b)
{
int m;
m= * a;
* a= * b;
* b= m;
}
void perm ( int list[ ] , int k, int m)
{
int i;
if ( k== m)
{
for ( i= 0 ; i<= m; i++ )
printf ( "%d " , list[ i] ) ;
printf ( "\n" ) ;
n++ ;
}
else
{
for ( i= k; i<= m; i++ )
{
swap ( & list[ k] , & list[ i] ) ;
perm ( list, k+ 1 , m) ;
swap ( & list[ k] , & list[ i] ) ;
}
}
}
int main ( void )
{
int list[ ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 } ;
perm ( list, 0 , 6 ) ;
printf ( "total:%d\n" , n) ;
system ( "pause" ) ;
return 0 ;
}
#include <stdio.h>
#include <stdlib.h>
void swap ( int * a, int * b)
{
int m;
m= * a;
* a= * b;
* b= m;
}
void perm ( int list[ ] , int len)
{
int i= 0 ;
int k= 0 ;
int n= len;
int j= 1 ;
for ( ; j<= len; j++ )
{
if ( list[ j- 1 ] < list[ j] )
i= j;
}
for ( j= 1 ; j<= len; j++ )
{
if ( list[ i- 1 ] < list[ j] )
k= j;
}
swap ( & list[ i- 1 ] , & list[ k] ) ;
for ( j= 0 ; j<= i; j++ )
{
printf ( "%d " , list[ j] ) ;
}
for ( j= len; j> i; j-- )
{
printf ( "%d " , list[ j] ) ;
}
}
int main ( void )
{
int list[ ] = { 7 , 6 , 4 , 1 , 3 , 5 , 2 } ;
perm ( list, 6 ) ;
system ( "pause" ) ;
return 0 ;
}
最大子段和
#include <cstdio>
#include <algorithm>
using namespace std;
int a[ 110 ] ;
int maxsum ( int l, int r)
{
if ( l== r)
{
return a[ l] ;
}
int mid = ( l+ r) / 2 ;
int lsum = maxsum ( l, mid) ;
int rsum = maxsum ( mid+ 1 , r) ;
int sum1= 0 , sum2= 0 ;
int lefts= 0 , rights= 0 ;
for ( int i= mid; i>= l; i-- )
{
lefts+ = a[ i] ;
if ( lefts> sum1)
{
sum1= lefts;
}
}
for ( int i= mid+ 1 ; i<= r; i++ )
{
rights+ = a[ i] ;
if ( rights> sum2)
{
sum2= rights;
}
}
int msum= sum1+ sum2;
return max ( msum, max ( lsum, rsum) ) ;
}
int main ( )
{
int n;
int ans;
while ( scanf ( "%d" , & n) != EOF )
{
for ( int i= 1 ; i<= n; i++ )
{
scanf ( "%d" , & a[ i] ) ;
}
ans = maxsum ( 0 , n) ;
if ( ans< 0 )
{
ans= 0 ;
}
printf ( "%d\n" , ans) ;
}
}
第三章
编程实现矩阵连乘问题的求解
输入
6
30 35
35 15
15 5
5 10
10 20
20 25
输出
15125
#include <stdio.h>
const int N= 100 ;
int p[ N] ;
int m[ N] [ N] ;
int s[ N] [ N] ;
void MatrixChain ( int n)
{
for ( int i = 1 ; i <= n; i++ ) m[ i] [ i] = 0 ;
for ( int r = 2 ; r <= n; r++ )
for ( int i = 1 ; i <= n - r+ 1 ; i++ )
{
int j= i+ r- 1 ;
m[ i] [ j] = m[ i+ 1 ] [ j] + p[ i- 1 ] * p[ i] * p[ j] ;
s[ i] [ j] = i;
for ( int k = i+ 1 ; k < j; k++ )
{
int t = m[ i] [ k] + m[ k+ 1 ] [ j] + p[ i- 1 ] * p[ k] * p[ j] ;
if ( t < m[ i] [ j] ) { m[ i] [ j] = t; s[ i] [ j] = k; }
}
}
}
void TraceBack ( int i, int j)
{
if ( i== j) return ;
else
{
TraceBack ( i, s[ i] [ j] ) ;
TraceBack ( s[ i] [ j] + 1 , j) ;
}
}
int main ( )
{
int n;
scanf ( "%d" , & n) ;
int i, temp;
for ( i= 0 ; i< n; i++ )
scanf ( "%d%d" , & p[ i] , & temp) ;
p[ n] = temp;
MatrixChain ( n) ;
TraceBack ( 1 , n) ;
printf ( "%d\n" , m[ 1 ] [ n] ) ;
return 0 ;
}
编程实现最大子段和
#include <stdio.h>
int Maxsum ( int * arr, int left, int right) {
int sum= 0 ;
if ( left== right) {
return arr[ right] > 0 ? arr[ right] : 0 ;
}
else {
int center= ( left+ right) / 2 ;
int leftsum= Maxsum ( arr, left, center) ;
int rightsum= Maxsum ( arr, center+ 1 , right) ;
int lm= 0 ;
int leftm= 0 ;
int rm= 0 ;
int rightm= 0 ;
for ( int i= center; i>= left; i-- ) {
leftm+ = arr[ i] ;
if ( leftm> lm) {
lm= leftm;
}
}
for ( int i= center+ 1 ; i<= right; i++ ) {
rightm+ = arr[ i] ;
if ( rightm> rm) {
rm= rightm;
}
}
sum= lm+ rm;
if ( sum< leftsum)
sum= leftsum;
if ( sum< rightsum)
sum= rightsum;
}
return sum;
}
int main ( ) {
int n;
scanf ( "%d" , & n) ;
int arr[ n+ 1 ] ;
for ( int i= 1 ; i<= n; i++ ) {
scanf ( "%d" , & arr[ i] ) ;
}
printf ( "%d" , Maxsum ( arr, 1 , n) ) ;
return 0 ;
}
0-1背包
#include <stdio.h>
#include <string.h>
int dp[ 1001 ] [ 1001 ] = { 0 } ;
int volume[ 1001 ] ;
int value[ 1001 ] ;
int max ( int a, int b)
{
if ( a> b) return a;
return b;
}
int main ( )
{
int n, v;
memset ( dp, 0 , sizeof ( dp) ) ;
scanf ( "%d%d" , & n, & v) ;
for ( int i= 1 ; i<= n; i++ )
scanf ( "%d%d" , & volume[ i] , & value[ i] ) ;
int maxNum = 0 ;
for ( int i= 1 ; i<= n; i++ )
for ( int j= 0 ; j<= v; j++ )
{
dp[ i] [ j] = dp[ i- 1 ] [ j] ;
if ( j>= volume[ i] )
{
dp[ i] [ j] = max ( dp[ i- 1 ] [ j] , dp[ i- 1 ] [ j- volume[ i] ] + value[ i] ) ;
if ( dp[ i] [ j] > maxNum) maxNum = dp[ i] [ j] ;
}
}
printf ( "%d\n" , maxNum) ;
return 0 ;
}
最长单调子序列
#include <stdio.h>
int a[ 100 ] , s[ 100 ] , dis, cot, n, maxz;
int dp[ 100 ] ;
int max ( int a, int b)
{
if ( a> b) return a;
return b;
}
int main ( )
{
scanf ( "%d" , & n) ;
for ( int i= 1 ; i<= n; i++ ) scanf ( "%d" , & a[ i] ) ;
for ( int i= 1 ; i<= n; i++ )
{
dp[ i] = 1 ;
for ( int j= 1 ; j<= i- 1 ; j++ )
{
if ( a[ j] < a[ i] )
{
dp[ i] = max ( dp[ i] , dp[ j] + 1 ) ;
if ( dp[ i] >= maxz)
dis= i;
maxz= max ( maxz, dp[ i] ) ;
}
}
}
printf ( "%d\n" , maxz) ;
int count= 1 , cot= maxz;
s[ 1 ] = a[ dis] ;
for ( int i= dis- 1 ; i>= 1 ; i-- )
{
if ( dp[ i] == cot- 1 )
{
s[ ++ count] = a[ i] ;
cot= dp[ i] ;
}
}
for ( int i= count; i>= 1 ; i-- ) printf ( "%d " , s[ i] ) ;
return 0 ;
}
最长公共子序列(LCS)
#include <stdio.h>
#include <string.h>
int c[ 200 ] [ 200 ] ;
int b[ 200 ] [ 200 ] ;
char f[ 200 ] ;
int Max ( int m, int n, int i, int j)
{
if ( m > n)
{
b[ i] [ j] = - 1 ;
return m;
}
else
{
b[ i] [ j] = 1 ;
return n;
}
}
int LCS ( char x[ ] , char y[ ] )
{
int i, j;
int x_len, y_len;
x_len = strlen ( x) ;
y_len = strlen ( y) ;
for ( i = 1 ; i <= x_len; i++ )
{
for ( j = 1 ; j <= y_len; j++ )
{
if ( x[ i- 1 ] == y[ j- 1 ] )
{
c[ i] [ j] = c[ i- 1 ] [ j- 1 ] + 1 ;
b[ i] [ j] = 0 ;
}
else
{
c[ i] [ j] = Max ( c[ i- 1 ] [ j] , c[ i] [ j- 1 ] , i, j) ;
}
}
}
return c[ x_len] [ y_len] ;
}
int main ( )
{
char X[ 200 ] , Y[ 200 ] ;
int i, j, s;
scanf ( "%s" , X) ;
scanf ( "%s" , Y) ;
s = LCS ( X, Y) ;
printf ( "%d\n" , s) ;
return 0 ;
}
聪明的寻宝人
#include <iostream>
using namespace std;
void MaxValue ( int values[ ] , int weights[ ] , int n, int m)
{
int dp[ n] [ m+ 1 ] ;
for ( int i= 0 ; i< n; i++ ) {
dp[ i] [ 0 ] = 0 ;
for ( int j= 1 ; j< m+ 1 ; j++ ) {
if ( i== 0 ) {
if ( j> weights[ i] ) {
dp[ i] [ j] = values[ i] ;
}
else {
dp[ i] [ j] = 0 ;
}
}
else {
if ( j< weights[ i] ) {
dp[ i] [ j] = dp[ i- 1 ] [ j] ;
}
else {
dp[ i] [ j] = dp[ i- 1 ] [ j- weights[ i] ] + values[ i] > dp[ i- 1 ] [ j] ? dp[ i- 1 ] [ j- weights[ i] ] + values[ i] : dp[ i- 1 ] [ j] ;
}
}
}
}
printf ( "%d" , dp[ n- 1 ] [ m] ) ;
}
基因检测
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
void Similar ( char * str1, char * str2)
{
int c[ 200 ] [ 200 ] ;
int i, j;
int x_len, y_len;
x_len = strlen ( str1) ;
y_len = strlen ( str2) ;
int flag= 1 ;
for ( i = 1 ; i <= x_len; i++ )
{
for ( j = 1 ; j <= y_len; j++ )
{
if ( str1[ i- 1 ] == str2[ j- 1 ] )
{
if ( flag== 1 ) {
c[ i] [ j] = c[ i- 1 ] [ j- 1 ] + 1 ;
}
else {
c[ i- 1 ] [ j- 1 ] = 0 ;
c[ i] [ j] = c[ i- 1 ] [ j- 1 ] + 1 ;
flag= 1 ;
}
}
else
{
flag= 0 ;
c[ i] [ j] = c[ i- 1 ] [ j] > c[ i] [ j- 1 ] ? c[ i- 1 ] [ j] : c[ i] [ j- 1 ] ;
}
}
}
printf ( "%d" , c[ x_len] [ y_len] ) ;
}
找相似串
#include <iostream>
#include <cstring>
using namespace std;
int max_l ( char * str1, char * str2)
{
int c[ 200 ] [ 200 ] ;
int i, j;
int x_len, y_len;
x_len = strlen ( str1) ;
y_len = strlen ( str2) ;
int flag= 1 ;
for ( i = 1 ; i <= x_len; i++ )
{
for ( j = 1 ; j <= y_len; j++ )
{
if ( str1[ i- 1 ] == str2[ j- 1 ] )
{
c[ i] [ j] = c[ i- 1 ] [ j- 1 ] + 1 ;
}
else
{
c[ i] [ j] = c[ i- 1 ] [ j] > c[ i] [ j- 1 ] ? c[ i- 1 ] [ j] : c[ i] [ j- 1 ] ;
}
}
}
return c[ x_len] [ y_len] ;
}
void Similar ( )
{
char a[ 50 ] ;
scanf ( "%s" , a) ;
int n;
scanf ( "%d" , & n) ;
char b[ n] [ 50 ] ;
int c[ n] , len1= strlen ( a) , min;
for ( int i= 0 ; i< n; i++ ) {
scanf ( "%s" , b[ i] ) ;
}
for ( int i= 0 ; i< n; i++ ) {
c[ i] = max_l ( a, b[ i] ) ;
int len2= strlen ( b[ i] ) ;
int into= len1- c[ i] ;
int del= len2- c[ i] ;
c[ i] = del+ into;
if ( i== 0 ) { min= c[ i] ; }
min= min< c[ i] ? min: c[ i] ;
}
for ( int i= 0 ; i< n; i++ ) {
if ( c[ i] == min) {
printf ( "%s\n" , b[ i] ) ;
}
}
}
第四章
活动安排
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
const int N= 10010 ;
int n;
struct Time
{
int B;
int E;
} s[ N] ;
int cmp ( const void * a, const void * b) {
if ( ( * ( struct Time * ) a) . B== ( * ( struct Time * ) b) . B) {
if ( ( * ( struct Time * ) a) . E<= ( * ( struct Time * ) b) . E) {
return - 1 ;
}
return 1 ;
}
else {
if ( ( * ( struct Time * ) a) . E< ( * ( struct Time * ) b) . E) {
return - 1 ;
}
return 1 ;
}
}
int main ( ) {
scanf ( "%d" , & n) ;
for ( int i= 0 ; i< n; i++ ) {
scanf ( "%d%d" , & s[ i] . B, & s[ i] . E) ;
}
qsort ( s, n, sizeof ( struct Time) , cmp) ;
int cnt= 0 ;
int t= 0 ;
for ( int i= 0 ; i< n; i++ ) {
if ( s[ i] . B>= t) {
cnt++ ;
t= s[ i] . E;
}
}
printf ( "%d\n" , cnt) ;
return 0 ;
}
最优装载问题
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
const int N= 100010 ;
int n, c;
int w[ N] ;
int cmp ( const void * a , const void * b)
{
return * ( int * ) a- * ( int * ) b;
}
int main ( ) {
scanf ( "%d%d" , & n, & c) ;
for ( int i= 0 ; i< n; i++ ) {
scanf ( "%d" , & w[ i] ) ;
}
int cnt= 0 ;
qsort ( w, n, sizeof ( int ) , cmp) ;
for ( int i= 0 ; i< n; i++ ) {
if ( w[ i] <= c) {
c- = w[ i] ;
cnt++ ;
}
}
printf ( "%d\n" , cnt) ;
return 0 ;
}
背包问题
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
const int N= 20 ;
int s, m;
struct jiazhi{
int w;
int v;
} jia[ N] ;
int cmp ( const void * a, const void * b) {
if ( ( * ( struct jiazhi * ) a) . v> ( * ( struct jiazhi * ) b) . v) {
return - 1 ;
}
return 1 ;
}
int main ( ) {
scanf ( "%d%d" , & s, & m) ;
for ( int i= 0 ; i< s; i++ ) {
scanf ( "%d%d" , & jia[ i] . v, & jia[ i] . w) ;
}
int sum= 0 ;
qsort ( jia, s, sizeof ( struct jiazhi) , cmp) ;
for ( int i= 0 ; i< s; i++ ) {
if ( jia[ i] . w>= m) {
sum+ = m* jia[ i] . v;
break ;
}
else {
m- = jia[ i] . w;
sum+ = jia[ i] . w* jia[ i] . v;
}
}
printf ( "%d\n" , sum) ;
return 0 ;
}
会场安排
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
const int N= 10010 ;
int n;
int ch[ N] ;
struct Time
{
int B;
int E;
} s[ N] ;
int cmp ( const void * a, const void * b) {
if ( ( * ( struct Time * ) a) . B== ( * ( struct Time * ) b) . B) {
if ( ( * ( struct Time * ) a) . E<= ( * ( struct Time * ) b) . E) {
return - 1 ;
}
return 1 ;
}
else {
if ( ( * ( struct Time * ) a) . E< ( * ( struct Time * ) b) . E) {
return - 1 ;
}
return 1 ;
}
}
int main ( ) {
scanf ( "%d" , & n) ;
for ( int i= 0 ; i< n; i++ ) {
scanf ( "%d%d" , & s[ i] . B, & s[ i] . E) ;
}
qsort ( s, n, sizeof ( struct Time) , cmp) ;
int cnt= 0 ;
for ( int i= 0 ; i< n; i++ ) {
for ( int j= 0 ; j<= cnt; j++ ) {
if ( s[ i] . B>= ch[ cnt] ) {
ch[ cnt] = s[ i] . E;
break ;
}
else {
cnt++ ;
ch[ cnt] = s[ i] . E;
break ;
}
}
}
printf ( "%d\n" , cnt) ;
return 0 ;
}
删数问题
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
const int N= 250 ;
char s[ N] ;
int n;
int main ( ) {
scanf ( "%s" , & s) ;
scanf ( "%d" , & n) ;
while ( n) {
for ( int i= 0 ; i< strlen ( s) ; i++ ) {
if ( s[ i] > s[ i+ 1 ] ) {
for ( int j= i; j< strlen ( s) ; j++ ) {
s[ j] = s[ j+ 1 ] ;
}
n-- ;
break ;
}
}
}
for ( int i= 0 ; i< strlen ( s) - n; i++ ) {
printf ( "%c" , s[ i] ) ;
}
return 0 ;
}
删除数字问题
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int main ( int argc, const char * argv[ ] ) {
char s[ 1001 ] ;
int a[ 1001 ] ;
int k;
int n;
scanf ( "%s" , & s) ;
scanf ( "%d" , & k) ;
int len= strlen ( s) ;
for ( int i= 0 ; i< strlen ( s) ; i++ ) {
a[ i] = s[ i] - '0' ;
}
int m= len;
while ( k) {
for ( int i= 0 ; i< len; i++ ) {
int j= i+ 1 ;
while ( a[ j] == - 1 ) {
j++ ;
}
if ( a[ i] < a[ j] && a[ i] != - 1 ) {
a[ i] = - 1 ;
k-- ;
break ;
}
if ( i== m- 1 ) {
a[ i] = - 1 ;
k-- ;
m-- ;
break ;
}
}
}
for ( int i= 0 ; i< len; i++ ) {
if ( a[ i] == - 1 ) continue ;
else printf ( "%d" , a[ i] ) ;
}
return 0 ;
}
第五章
排列
#include <stdio.h>
int m, n;
int a[ 30 ] ;
bool check ( int i) {
for ( int j= 0 ; j< i; j++ ) {
if ( a[ i] == a[ j] ) {
return false;
}
}
return true;
}
void backtrack ( int i, int m, int n) {
if ( i>= n) {
for ( int i= 0 ; i< n; i++ ) {
if ( i== n- 1 ) {
printf ( "%c" , 'A' + a[ i] ) ;
}
else printf ( "%c " , 'A' + a[ i] ) ;
}
printf ( "\n" ) ;
}
else {
for ( int j= 0 ; j< m; j++ ) {
a[ i] = j;
if ( check ( i) ) {
backtrack ( i+ 1 , m, n) ;
}
}
}
}
int main ( ) {
scanf ( "%d%d" , & m, & n) ;
int a[ m] ;
backtrack ( 0 , m, n) ;
return 0 ;
}
子集合
#include <stdio.h>
int s[ 100 ] ;
int s1[ 100 ] ;
int n;
int c;
int cw;
int r;
int best;
bool flag;
void BackTrack ( int i)
{
if ( i > n) {
if ( cw == c) {
int cnt= 0 ;
for ( int i = 1 ; i <= n; i++ )
if ( s1[ i] == 1 && cnt== 0 ) { cnt++ ; printf ( "%d" , s[ i] ) ; }
else if ( s1[ i] == 1 && cnt!= 0 ) printf ( " %d" , s[ i] ) ;
printf ( "\n" ) ;
flag = false;
}
best = cw;
return ;
}
if ( cw + s[ i] <= c) {
s1[ i] = 1 ;
cw + = s[ i] ;
BackTrack ( i + 1 ) ;
cw - = s[ i] ;
}
r - = s[ i] ;
if ( cw + r > best) {
s1[ i] = 0 ;
BackTrack ( i + 1 ) ;
}
r + = s[ i] ;
}
int main ( )
{
scanf ( "%d%d" , & n, & c) ;
r = 0 ;
for ( int i = 1 ; i <= n; i++ )
{
scanf ( "%d" , & s[ i] ) ;
r+ = s[ i] ;
}
cw = 0 ;
best = 0 ;
flag = true;
BackTrack ( 1 ) ;
if ( flag == true) printf ( "No Solution!\n" ) ;
}
TSP问题
#include <stdio.h>
const int N= 100 ;
int n;
int b[ 8 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 } ;
int a[ N] [ N] , x[ 8 ] ;
int min= 1000 ;
void swap ( int & a, int & b)
{
int t= a;
a= b;
b= t;
}
void dfs ( int i, int dis)
{
if ( dis>= min)
return ;
else if ( i== n)
{
if ( dis+ a[ b[ i- 1 ] ] [ 1 ] < min)
{
min= dis+ a[ b[ i- 1 ] ] [ 1 ] ;
for ( int j= 1 ; j< n; j++ )
x[ j] = b[ j] ;
}
return ;
}
else
{
for ( int j= i; j< n; j++ )
{
swap ( b[ i] , b[ j] ) ;
dfs ( i+ 1 , dis+ a[ b[ i- 1 ] ] [ b[ i] ] ) ;
swap ( b[ i] , b[ j] ) ;
}
}
}
int main ( ) {
scanf ( "%d" , & n) ;
for ( int i= 1 ; i<= n; i++ ) {
for ( int j= 1 ; j<= n; j++ ) {
scanf ( "%d" , & a[ i] [ j] ) ;
}
}
dfs ( 1 , 0 ) ;
printf ( "%d\n" , min) ;
printf ( "1" ) ;
for ( int i= 1 ; i< n; i++ )
printf ( " %d" , x[ i] ) ;
printf ( " 1" ) ;
return 0 ;
}
n皇后问题
#include <stdio.h>
#include <math.h>
int check ( int a[ ] , int n) {
for ( int i= 0 ; i< n; i++ ) {
if ( a[ i] == a[ n] || abs ( n- i) == abs ( a[ n] - a[ i] ) ) {
return 0 ;
}
}
return 1 ;
}
void queen ( int a[ ] , int n, int & res, int len) {
if ( n== len) {
res++ ;
}
else {
for ( int j= 0 ; j< len; j++ ) {
a[ n] = j;
if ( check ( a, n) ) {
queen ( a, n+ 1 , res, len) ;
}
}
}
}
int main ( ) {
while ( 1 ) {
int n;
scanf ( "%d" , & n) ;
if ( n== 0 ) break ;
int a[ n] ;
for ( int i= 0 ; i< n; i++ ) {
a[ i] = 0 ;
}
int res= 0 ;
queen ( a, 0 , res, n) ;
printf ( "%d\n" , res) ;
}
return 0 ;
}
0-1背包
#include <stdio.h>
#include <stdlib.h>
void value ( int w[ ] , int v[ ] , int b[ ] , int n, int c, int & maxv, int len) {
if ( n== len) {
int weight= 0 , value= 0 ;
for ( int i= 0 ; i< len; i++ ) {
if ( b[ i] == 1 ) {
weight+ = w[ i] ;
value+ = v[ i] ;
}
}
if ( weight<= c) {
maxv= maxv> value? maxv: value;
}
return ;
}
else {
b[ n] = 1 ;
value ( w, v, b, n+ 1 , c, maxv, len) ;
b[ n] = 0 ;
value ( w, v, b, n+ 1 , c, maxv, len) ;
}
}
int main ( ) {
int n, c;
scanf ( "%d%d" , & n, & c) ;
int w[ n] , v[ n] , b[ n] = { 0 } ;
for ( int i= 0 ; i< n; i++ ) {
scanf ( "%d" , & w[ i] ) ;
}
for ( int i= 0 ; i< n; i++ ) {
scanf ( "%d" , & v[ i] ) ;
}
int maxv= 0 ;
value ( w, v, b, 0 , c, maxv, n) ;
printf ( "%d\n" , maxv) ;
return 0 ;
}
图的m着色问题
#include <iostream>
using namespace std;
int n;
int r;
int m;
int side[ 20 ] [ 20 ] ;
int color[ 20 ] ;
int plan= 0 ;
void dfs ( int k) ;
bool canpaint ( int k, int c) ;
int main ( )
{
int i, u, v;
cin>> n>> r>> m;
for ( i= 0 ; i< r; i++ )
{
cin>> u>> v;
side[ u] [ v] = side[ v] [ u] = 1 ;
}
dfs ( 0 ) ;
cout<< plan<< endl;
return 0 ;
}
void dfs ( int k)
{
if ( k== n)
{
plan++ ;
}
else
{
for ( int c= 1 ; c<= m; c++ )
{
if ( canpaint ( k, c) )
{
color[ k] = c;
dfs ( k+ 1 ) ;
}
}
}
}
bool canpaint ( int k, int c)
{
for ( int i= 0 ; i< k; i++ )
{
if ( side[ k] [ i] == 1 && color[ i] == c)
return false;
}
return true;
}
n位逐位整除数
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
void backtrack ( int * a, int t, int n, int & sum)
{
if ( t== n+ 1 ) {
int y= 0 , m= 0 ;
for ( int i= 0 ; i< n; i++ ) {
y= ( m* 10 + a[ i] ) % n;
m= y;
}
if ( y== 0 ) {
sum++ ;
}
}
else {
if ( t== 1 ) {
for ( int i= 1 ; i< 10 ; i++ ) {
a[ t- 1 ] = i;
backtrack ( a, t+ 1 , n, sum) ;
}
}
else {
int y= 0 , m= 0 ;
for ( int i= 0 ; i< t- 1 ; i++ ) {
y= ( m* 10 + a[ i] ) % ( t- 1 ) ;
m= y;
}
if ( y== 0 ) {
for ( int i= 0 ; i< 10 ; i++ ) {
a[ t- 1 ] = i;
backtrack ( a, t+ 1 , n, sum) ;
}
}
}
}
}
int main ( int argc, const char * argv[ ] ) {
int a[ 101 ] ;
int n;
scanf ( "%d" , & n) ;
int sum = 0 ;
backtrack ( a, 1 , n, sum) ;
printf ( "%d\n" , sum) ;
return 0 ;
}
素数圈
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
int n;
int ans[ 110 ] , used[ 110 ] ;
bool isPrime ( int sum)
{
for ( int i= 2 ; i<= sqrt ( sum) ; i++ )
{
if ( sum% i== 0 )
{
return false;
}
}
return true;
}
bool isMeetA ( int step)
{
if ( step== 1 )
{
return true;
}
else
{
if ( isPrime ( ans[ step- 1 ] + ans[ step] ) )
{
if ( step== n)
{
if ( isPrime ( ans[ step] + ans[ 1 ] ) )
{
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}
else
{
return false;
}
}
}
bool dfs ( int step)
{
if ( step== n+ 1 )
{
printf ( "围成的圈是:" ) ;
for ( int i= 1 ; i<= n; i++ )
{
printf ( "%d " , ans[ i] ) ;
}
printf ( "\n" ) ;
return true;
}
else
{
for ( int i= 1 ; i< n+ 1 ; i++ )
{
if ( ! used[ i] )
{
used[ i] = 1 ;
ans[ step] = i;
if ( isMeetA ( step) )
{
if ( dfs ( step+ 1 ) )
{
return true;
}
}
used[ i] = 0 ;
ans[ step] = 0 ;
}
}
return false;
}
}
int main ( )
{
scanf ( "%d" , & n) ;
dfs ( 1 ) ;
return 0 ;
}