题目链接: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;
}