USACO 2.1-Healthy Holsteins

题目链接:http://train.usaco.org/usacoprob2?a=ckp2K41VOuH&S=holstein

/*
ID: m1590291
TASK: holstein
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;
/****************************************************************************************************************
                题意:大致是搜索找最优解之类的
                思路:
                1,考虑 dfs 一定可以达到目的,能确定是否存在满足的解
                2,回溯
                    a,找不到满足的解,直接回溯
                    b,找到满足的解,更新状态并回溯(确保状态为最优)
                3,状态如何表示
                    a,每次在dfs的时候临时储存走过的长度以及路径  num:长度,id[i]: 路径
                    b,若最后满足目的,即满足(2.b),则更新状态
                    c,不满足目的时回溯了,重新储存临时变量,即长度和路径

****************************************************************************************************************/
int m,n;
int temp[30],ans[20],id[20],V[30];
int a[20][30];
int minN=2147483647;
void dfs(int deep,int num)
{
    if(deep == m+1){        //回溯
        for(int i = 1;i <= n;i ++)      //不满足目的
            if(temp[i] < V[i])
                return ;
        if(num < minN){     //满足目的且当前路径为最优
            minN=num;
            for(int i = 1;i <= minN;i ++)
                ans[i]=id[i];
        }
        return ;
    }
    for(int i = 1;i <= n;i ++)
        temp[i]+=a[deep][i];
    id[num+1]=deep;     //dfs中临时记录路径和长度
    dfs(deep+1,num+1);

    for(int i = 1;i <= n;i ++)      //上一决策不能达到目的,回溯并从下一层开始dfs
        temp[i]-=a[deep][i];
    dfs(deep+1,num);
}
int main()
{
    ifstream fin("holstein.in");
    ofstream fout("holstein.out");

    while(fin>>n)
    {
        for(int i = 1;i <= n;i ++)  fin>>V[i];
        fin>>m;
        for(int i = 1;i <= m;i ++)
            for(int j = 1;j <= n;j ++)
                fin>>a[i][j];

        memset(temp,0,sizeof(temp));

        dfs(1,0);

        fout<<minN;     //打印最短路径长度即路径
        for(int i = 1;i <= minN;i ++)
            fout<<" "<<ans[i];
        fout<<endl;
    }
    return 0;
}



 

posted on 2016-04-25 17:35  Jstyle  阅读(124)  评论(0编辑  收藏  举报

导航