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; }