NOIP2014模擬11 1B組 蜀傳之單刀赴會

2021-09-10 23:00:30 字數 1973 閱讀 2854

論壇中我的總結:

這題用狀壓dp實現。

我們先對於起點和終點,以及朋友家每個跑一遍spfa,將這些點定義為關鍵點,兩兩之間都求出了最短路,然後我們可以用狀壓dp來解決問題。

我們可以設f[i][j]表示當前到達點i,走過朋友家的狀態為j的最短路。這是從1到n的!

然後我們再設g[i][j]表示當前到達點j,走過朋友家的狀態為j的最短路。這是從n到1的!

而f的初始值為:f[0][0]=0;(0表示起點,k+1表示終點)

g的初始值為:g[k+1]=f[k+1];

最後的答案在g[0]中找即可。

這題就是個狀壓dp,我們設:

做完f後就把f[k]賦值為g[k],然後在照做一遍就可以了。

我們可以將第0個朋友表示為1,第k+1個朋友表示為n。

上標:

#include

#include

#include

#define n 10010

#define m 50010

#define ll long long

using namespace std;

struct nodee[m<<2]

;int n,m,k,t,tail[n]

,cnt=

0,f[n<<3]

,fd[17]

,x,ans=0;

ll d[n]

,dis[17]

[17],f[17]

[70010

],g[17]

[70010

],time;

bool bz[n]

;inline

intread()

inline

void

add(

int u,

int v,

int l)

; tail[u]

=cnt;

}void

spfa

(int x)

bz[f[l]]=

0;}}

intchange

(int x)

intmain()

for(

int i=

1;i<=k;i++

) fd[i]

=read()

; fd[0]

=1;fd[

++k]

=n;for

(int i=

0;i<=k;i++)/*

for (int i=0;i<=k;i++)

*/memset

(f,60

,sizeof

(f))

;f[0][

0]=0

;for

(int j=

0;j<=(1

<;j++

)for

(int i=

0;i<=k;i++)}

memset

(g,60

,sizeof

(g))

;for

(int i=

0;i<=(1

<;i++

) g[k]

[i]=f[k]

[i];

for(

int j=

0;j<=(1

<;j++

)for

(int i=k;i>=

0;i--)}

for(

int i=

0;i<=(1

<;i++)if

(g[0

][i]

<=t)

if(ans==0)

puts

("-1");

else

printf

("%d %lld\n"

,ans-

1,time)

;return0;

}

NOIP2014模擬11 1B組 吳傳之火燒連營

trie,動態開點。我們可以將輸入的a,b全部看成二進位制數。然後按照二進位制中的位置從大到小開始建trie。如果trie不會的可以自己手動普及一下。建好a的trie後,我們可以對於每個b i 開始求答案。答案可以說是貪心來求的。正確性可以保證。如果對於當前結點 1 只有乙個兒子,那就走那乙個兒子。...

NOIP2014模擬11 1B組 吳傳之火燒連營

trie,動態開點。我們可以將輸入的a,b全部看成二進位制數。然後按照二進位制中的位置從大到小開始建trie。如果trie不會的可以自己手動普及一下。建好a的trie後,我們可以對於每個b i 開始求答案。答案可以說是貪心來求的。正確性可以保證。如果對於當前結點 1 只有乙個兒子,那就走那乙個兒子。...

NOIP2014提高組模擬題 8 9

一 最大配對 題意 給兩個序列,要求選k組,每組從兩個序列中各選乙個數,要使各組數的差的和最大。小論 兩個序列分別排序。每次用乙個序列的最大的減另乙個序列的最小的。當時情況 估計100分,結果50分。雖然題目有提醒答案可能超過2 31 1,我也看到了,但想著等下打完再改,於是我打著打著就忘了 最後掛...