USACO-Healthy Holsteins

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;
}
posted @ 2012-10-22 17:25  ay27  阅读(174)  评论(0编辑  收藏  举报