t1題面
首先我們很容易發現乙個操作序列是否合法與操作序列的順序是無關的,選定操作之後加上階乘即可。
我們從小到大dfs,對於第i次操作我們把序列分成2^(n-i)段,每段長度2^i。
我們(用check函式)找到序列中不是連續遞增的段,如果這樣的段超過2個,這當然不可能,直接退出。
沒有這樣的段就不用操作。
有一段的話判斷一下交換前後一半之後是否滿足要求。
有兩段的話和一段也很像。
#includeusing namespace std;
namespace program//預處理
inline void dfs(long long k,long long now)
long long pos1=0,pos2=0;//pos1表示第一段的頭指標,pos2表示第二段的頭指標
for(long long i=1;i<=bin[n];i+=bin[k])else if(!pos2)else}}
if(!pos1&&!pos2)else if(pos1&&!pos2)else
swap(pos1+x*bin[k-1],pos2+y*bin[k-1],k-1);//當前情況錯誤返回 }}
}}
inline void work()
inline void add(int x,int y)
inline void init()//雙向連邊
for(int i=1;i<=n;i++)//用來隨機搜尋的陣列
}inline void dfs(int x,int sum)
if(vis[b[x]]==sum)
dfs(x+1,sum+1);//答案加一
}else
}inline void work()
cout折半搜尋
每個數有不選、選、選成階乘三種方法。3^n 列舉前一半後一半,合併資訊即可。
#include#define n 110
using namespace std;
namespace program
inline void init()
inline void dfs1(long long pos,long long k,long long sum)
//乙個數有三種情況,選 不選 階乘
dfs1(pos+1,k,sum);//不選
dfs1(pos+1,k,sum+val[pos]);//選
if(val[pos]<=18)
}inline void dfs2(long long pos,long long k,long long sum)
dfs2(pos+1,k,sum);
dfs2(pos+1,k,sum+val[pos]);
if(val[pos]<=18)
}inline void work()
}cout這題主要考剪枝
可行性剪枝1:如果當前位置只能向上走和向下走,則返回。(可以證明,走上去就不能再下來了,走下來就不能再上去了)
可行性剪枝2:如果當前位置只能向左走和向右走,則返回。(可以證明,走左邊就不能再到右邊去了,走右邊就不能再到左邊去了)
最優性剪枝:如果當前最大影響值比已知答案還要大,則返回。
#include#define n 50
using namespace std;
namespace program;
const long long dy=;
//走的方向不用多說了吧
inline void init()
inline void dfs(long long num,long long x,long long y,long long ans)else
if(num==n*m)
if(limit[x-1][y]==limit[x+1][y]&&limit[x][y+1]==limit[x][y-1])
if(limit[x-1][y]||limit[x][y+1])
return;//可行性剪枝
//若只能上下走或左右走就跳掉
for(long long i=1;i<=4;i++)}}
inline void work()
}int main()
記憶化搜尋練習題
michael喜歡滑雪。這並不奇怪,因為滑雪的確很刺激。可是為了獲得速度,滑的區域必須向下傾斜,而且當你滑到坡底,你不得不再次走上坡或者等待公升降機來載你。michael想知道在乙個區域中最長的滑坡。區域由乙個二維陣列給出。陣列的每個數字代表點的高度。下面是乙個例子 1 2 3 4 5 16 17 ...
搜尋練習題(1)八皇后
檢查乙個如下的6 x 6的跳棋棋盤,有六個棋子被放置在棋盤上,使得每行 每列有且只有乙個,每條對角線 包括兩條主對角線的所有平行線 上至多有乙個棋子。上面的布局可以用序列2 4 6 1 3 5來描述,第i個數字表示在第i行的相應位置有乙個棋子,如下 行號 1 2 3 4 5 6 列號 2 4 6 1...
python書中練習題 python練習題
1 定義乙個空列表,接收從鍵盤輸入的整數,把列表傳給乙個從大到小排序的函式,再輸出排序後的列表的值 listex b 0 a int input 請輸入列表長度 while b a num int input 請輸入字元 b 1 print listex sum 0 for i in range 0...