2018.4.20
UVA572 油田 看了刘汝佳老师的紫皮书上的例题,应该是用了一种叫做洪水填充或者种子填充的算法
4.21
HDU1455 sticks 用了剪枝的思想
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 100; int a[maxn],v[maxn]; int p;//判断是否计算出最小值 int m;//输入的木棍个数m int cmp(int i,int j) { return i>j; } void dfs(int beg, int len, int aim, int num)//起始下标,木棍长度,目标长度,拼接的木棍总数 { if(p)return; if(num == m){ p = 1; return; } for(int i = beg; i < m; i ++) { if(a[i] + len <= aim && v[i] != 1) { v[i] = 1; if(a[i]+len == aim)dfs(0,0,aim,num+1); else{ dfs(i + 1, a[i] + len, aim, num+1);//这是个用num++就超时用++num就WA的地方 } v[i] = 0; if(p) return;//完成,返回 if(len == 0)return;//剪枝,如果前面的不满足条件,那么后面的也一定不满足 while(i < m && a[i+1] == a[i]) ++i;//剪枝,若不满足条件,则把不满足条件的长度相等的木棍跳过去 } } } int main() { int sum;//所有木棍的总长度 while(cin >> m && m!= 0) { memset(v,0,sizeof(v)); sum = 0; for(int i = 0; i < m; i ++) { cin >> a[i]; sum += a[i]; } sort(a,a+m,cmp); for(int i = a[0]; i <= sum; i ++) { if(i == sum)cout << sum << endl;//如果只有一个木棍,直接输出 else if(sum % i == 0)//剪枝 { p = 0; dfs(0,0,i,0); if(p) { cout << i << endl; break; } } } } return 0; }
4.23
HDU2553 N皇后问题 无论如何都超时,一气之下打了表
#include<iostream> #include<cstdio> #include<cstring> #include<ctime> using namespace std; int tot,n; int v[20][20]; void searchs(int r) { if(r >= n) { tot ++; return; } for(int i = 0; i < n; i ++) { if(!v[0][i]&&!v[1][r+i]&&!v[2][r-i+n]) { v[0][i] = v[1][r+i] = v[2][r-i+n] = 1; searchs(r+1); v[0][i] = v[1][r+i] = v[2][r-i+n] = 0; } } } int main() { while(scanf("%d",&n)&&n) { // clock_t start,ends; // start = clock(); tot = 0; memset(v,0,sizeof(v)); searchs(0); printf("%d\n",tot); // ends = clock(); // printf("time:%d\n",ends - start); } return 0; }