2018.8.22 練習賽
阿新 • • 發佈:2018-08-23
stdio.h 一行 fine content urn 整數 i++ class status
- T1 井字棋
- 題意:給定一井字棋殘局,問結果
- 狀壓記憶化暴搜,博弈
-
1 #include<stdio.h> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 int po[20],ch[256]; 7 int f[100000][3]; 8 int judge(int s) 9 { 10 int g[10]; 11 for(int i=1,ss=s;i<=9
View Code - T2 ?asuchy
- 題面:
(BZOJ)3749: [POI2015]?asuchy
Time Limit: 10 Sec Memory Limit: 64 MBSec Special Judge
Submit: 420 Solved: 164
[Submit][Status][Discuss]Description
圓桌上擺放著n份食物,圍成一圈,第i份食物所含熱量為c[i]。 相鄰兩份食物之間坐著一個人,共有n個人。每個人有兩種選擇,吃自己左邊或者右邊的食物。如果兩個人選擇了同一份食物,這兩個人會平分這份食物,每人獲得一半的熱量。 假如某個人改變自己的選擇後(其他n-1個人的選擇不變),可以使自己獲得比原先更多的熱量,那麽這個人會不滿意。 請你給每個人指定應該吃哪一份食物,使得所有人都能夠滿意。Input
第一行一個整數n(2<=n<=1000000),表示食物的數量(即人數)。食物和人都從1~n編號。 第二行包含n個整數c[1],c[2],…,c[n](1<=c[i]<=10^9)。 假設第i個人(1<=i<n)左邊是第i份食物,右邊是第i+1份食物;而第n個人左邊是第n份食物,右邊是第1份食物。Output
如果不存在這樣的方案,僅輸出一行NIE。 如果存在這樣的方案,輸出一行共n個整數,第i個整數表示第i個人選擇的食物的編號。如果有多組這樣的方案,輸出任意一個即可。Sample Input
5
5 3 7 2 9Sample Output
2 3 3 5 1- 狀態惡心的dp,狀態:f[i][j]表示第i個食物處於第j種狀態:被左邊吃,被右邊吃,被兩邊吃,兩邊都不吃,轉移見code(ps:不存在無解的情況!)話說似乎貪心+隨機化之類可以騙到大部分分……多跑幾遍說不定就A了……
-
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #define ll long long 5 using namespace std; 6 7 ll n; 8 ll a[1000005]; 9 ll f[1000005][5]; 10 ll ans[1000005]; 11 // 1 left 12 // 2 right 13 // 3 yiqi 14 // 4 doubu 15 16 bool dp(ll v) { 17 memset(f,0,sizeof(f)); 18 f[1][v]=1; 19 for(int i=2; i<=n; i++) { 20 if(f[i-1][1]&&a[i-1]<=2*a[i]) f[i][1]=1; 21 if(f[i-1][1]&&a[i-1]<=a[i]) f[i][3]=1; 22 if(f[i-1][2]&&a[i-1]*2>=a[i]) f[i][2]=2; 23 if(f[i-1][2]&&a[i-1]>=a[i]) f[i][4]=2; 24 if(f[i-1][3]&&a[i-1]>=a[i]*2) f[i][4]=3; 25 if(f[i-1][3]&&a[i-1]>=a[i]) f[i][2]=3; 26 if(f[i-1][4]&&a[i-1]<=a[i]) f[i][1]=4; 27 if(f[i-1][4]&&a[i-1]*2<=a[i]) f[i][3]=4; 28 } 29 if(!f[n][v]) return 0; 30 for(int i=n; i>=1; i--) { 31 if(v==1) ans[i-1]=(i-1)%(n-1)+1; 32 if(v==2) ans[i]=(i-1)%(n-1)+1; 33 if(v==3) ans[i-1]=ans[i]=(i-1)%(n-1)+1; 34 v=f[i][v]; 35 } 36 for(int i=1; i<n; i++) printf("%lld ",ans[i]); 37 return 1; 38 } 39 40 int main() { 41 scanf("%lld",&n); 42 for(int i=1; i<=n; i++) scanf("%lld",&a[i]); 43 a[++n]=a[1]; 44 for(int i=1;i<=4;i++) if(dp(i)) return 0; 45 }
View Code - T3 泰拉瑞亞
- 題意:完成兩個操作:單點增加某點的值,快速查找某點左右兩邊第一個比它值大的點。
- 這道真是毒瘤題……大概思路……分塊維護塊中單調棧,每個塊再用線段樹維護單點修改……代碼暫無……
2018.8.22 練習賽