http://ace.delos.com/usacoprob2?a=kPNDMRfiMdD&S=holstein
这题开始时看错题了,以为只需输出最少饲料数就行了。提交后发现出问题了,然后一直改,改得不像样了。。。。
这题的数据太小了,直接DFS就行了,就算搜遍整个搜索树,也就2^15吧,因为每种饲料只有用和不用两种情况,刚好对应二进制的0和1。
如果数据大了,估计就是DP了。
这题输出有一个比较坑的地方,它要选择最小的饲料序列输出,而我开始没看到要输出饲料,根本没关心这个。。。
程序很挫,看看就好了。
#include <iostream> #include <cstdio> #include <string.h> using namespace std; int r[100],f[20][100]; int d[100]; int n,m; bool flag[100]={false}; bool check() { for (int i=1;i<=n;i++) if (d[i]<r[i]) return false; return true; } int rr[100]={1000000,0}; void dfs(int dep,int x) //dep是饲料的序数,x是选择了几个饲料 { if (dep==m+1) { if (check() && x<=rr[0]) //记录饲料序列 { rr[0]=0; for (int i=1;i<=m;i++) if (flag[i]) rr[++rr[0]]=i; } return; } dfs(dep+1,x); //不选择在dep位置上的饲料 for (int i=1;i<=n;i++) d[i]+=f[dep][i]; flag[dep]=true; dfs(dep+1,x+1); //选择在dep位置上的饲料 flag[dep]=false; for (int i=1;i<=n;i++) d[i]-=f[dep][i]; } int main() { freopen("holstein.in","r",stdin); freopen("holstein.out","w",stdout); scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&r[i]); scanf("%d",&m); for (int i=1;i<=m;i++) for (int j=1;j<=n;j++) scanf("%d",&f[i][j]); memset(d,0,sizeof(d)); dfs(1,0); cout<<rr[0]; for (int i=1;i<=rr[0];i++) cout<<" "<<rr[i]; cout<<endl; return 0; }