jzoj 1261 數字遊戲

2021-08-06 03:57:33 字數 1638 閱讀 9516

charles和sunny在玩乙個簡單的遊戲。若給出1~n的乙個排列a,則將a1、a2相加,a2、a3相加……an-1、an相加,則得到一組n-1個元素的數列b;再將b1、b2相加,b2、b3相加,bn-2、bn-1相加,則得到一組n-2個元素的數列……如此往復,最終會得出乙個數t。而charles和sunny玩的遊戲便是,charles給出n和t,sunny在盡可能短的時間內,找到能通過上述操作得到t且字典序最小的1~n的排列。(sunny大聲說:「what an easy game!」,接著幾下就給出了解),charles覺得沒意思,就想和你玩,當然,你可以用一種叫做「電子計算機」的東西幫你。
本題有多組資料,對於每組資料:一行兩個整數n(0< n<=20),t即最後求出來的數。兩個0表示輸入結束。
對於每組測試資料輸出一行n個整數,用空格分開,行尾無多餘空格,表示求出來的滿足要求的1~n的乙個排列。
4 16

3 90 0

3 1 2 4

1 3 2

對於30%的資料,保證該組裡的每個n都不超過10。

對於100%的資料,保證有每個n不超過20,且每組資料的個數不超過10。

可以通過觀察發現,t是由這個n的排列的每個數乘上乙個係數得到,係數是楊輝三角第n行。

若直接dfs,就會超時,所以需要剪枝。

1.若已經找到答案,結束dfs

2.若當前的和加上後面能算出的最大值仍小於t,返回上層。

3.若當前的和加上後面能算出的最小值仍大於t,返回上層。

4.由於係數對稱,而要找字典序最小的序列,所以,當係數相同時,小的數一定在前面。

#include

#include

#include

#include

#include

using namespace std;

#define n 25

int f[n][n];

intq[n],t[n],x[n];

int n,m;

bool b;

void pre()

bool comp(int

x,int

y)bool pd(int dep,int

s) //printf("max=%d\n",an);

if (anan=s;

j=0;

for (int i=1;i<=n;++i)

if (t[i]==0)

//printf("min=%d\n",an);

if (an>m) return true;

return false;

}void dfs(int dep,int

s) return;

}if (s>m) return;

if (pd(dep+1,s)) return;

if (dep>n/2 && q[dep]

for (int i=1;i<=n;++i)

if (t[i]==0)

}int main()

return

0;}

JZOJ 數字遊戲 DP

小w發明了乙個遊戲,他在黑板上寫出了一行數字a1,a2,a3,an,然後給你m個回合的機會,每回合你可以從中選擇乙個數字擦去它,接著剩下來的每個數字ai都要遞減乙個值bi,即a1減掉b1,a2減掉b2,如此重複m個回合,所有你擦去的數字之和就是你所得的分數。小w和他的好朋友小y玩了這個遊戲,可是他發...

Jzoj 2032 數字遊戲

按某種順序在紙上寫下1 n 1 n 10 1 n 1 n 10 1 n 1 n 1 0 之間的所有數,然後把相鄰的數字相加,得到乙個比原數列少一項的數列。對新數列重複上述的操作,直到整個數列只剩乙個數為止。n 4 n 4n 4的時候,整個遊戲的流程可能如下所示 3 1 2 4 4 3 6 7 9 1...

jzoj數字遊戲 貪心 DP

description 一行數字a1,a2,a3,an,有m個回合,每個回合必須從中選擇乙個數字擦去它,接著每個回合後剩下來的每個數字ai都要遞減乙個相應的值bi。如此重複m個回合,所有你擦去的數字之和就是你所得的分數。給出n,m,a數列和b數列,求所得的最多的分數。input 輸入檔案的第一行是乙...