算法:
1.只有16种爱好,枚举所有可能,每种爱好要或不要,总共有65536种状态。
2.dfs直接枚举每种状态,并保持最优解,刚开始写搓了,dfs超时,原因是搜索没有控制好,搜索的状态变成16!
View Code
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<iostream> using namespace std; int dt[50][50]; int val[50]; int hash[100]; int visit[100]; int sum[100]; int tx[20]; int N, M, maxn; bool flag, final; void DFS(int num, int ans, int f) { if( flag ) return; if( num == M && ans < maxn ) return; if( num == M ) { //输出可以保留的活动数 if( f == N ) { final = true; if( ans == M ) { printf("%d",M); for( int i = 1; i <= M; i++) { printf(" %d", i); } flag = true; puts(""); } else if( ans > maxn ) { maxn = ans; int ix = 0; for( int i = 1; i <= M; i++) { if( visit[i] ) tx[ix++] = i; } } } return ; } for( int i = num + 1; i <= M; i++) { hash[i] = 1; visit[i] = 1; int temp = 0; for( int j = 1; j <= N; j++) { sum[j] += dt[i][j]; if( sum[j] >= val[j] ) temp++; } int ad = temp - f; DFS( num + 1, ans + 1, f + ad); //该方案要 visit[i] = 0; for( int j = 1; j <= N; j++) sum[j] -= dt[i][j]; DFS( num + 1, ans, f); //该方案不要 hash[i] = 0; break; } } int main( ) { //freopen( "1002.in","r",stdin ); //freopen( "10022.txt","w",stdout ); while( scanf("%d",&N) != EOF) { for(int i = 1; i <= N; i++) { scanf("%d",&val[i]); } scanf("%d",&M); for( int i = 1; i <= M; i++) { for( int j = 1; j <= N; j++) scanf("%d",&dt[i][j]); } memset(hash,0,sizeof(hash)); memset(visit,0,sizeof(visit)); memset(sum,0,sizeof(sum)); flag = false; final = false; maxn = -1; DFS( 0, 0, 0); if( !final ) puts("0"); else if( !flag ) { printf("%d",maxn); for( int i = 0; i < maxn; i++) printf(" %d",tx[i]); puts(""); } } return 0; }