日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Luogu P1280 Niko的任务【线性dp】By cellur925

發布時間:2025/3/15 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Luogu P1280 Niko的任务【线性dp】By cellur925 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Nikonikoni~~

題目傳送門

這是當時學長講dp的第一道例題,我還上去獻了個丑,然鵝學長講的方法我似董非董(???

我當時說的怎么設計這道題的狀態,但是好像說的是二維,本題數據范圍均在10000級別,n2肯定會空間炸掉的(然而我當時還不懂...)

所以本題的狀態肯定是一維的。

今天再做這道題,狀態很容易出來了,設f[i]為1~i時間(到第i刻)的最大閑暇時間。然后日常不會推轉移方程Orz。題解真香。

但,這個狀態看似是正確的而且很可做的樣子,但是我們仔細一想就會發現在這個狀態下轉移的漏洞:

  如果當前時刻有很多可以開始的任務,但他們的結束時間可能各不相同,那么所能獲得的閑暇時間就各有優劣了。正推看來是有弊病的。

那么我們就選擇逆推:

設f[i]表示i~n所能獲得的最大閑暇時間。我們還需要統計當前時刻有沒有任務開始了。

  如果當前時刻沒有任務,就繼承i+1時刻的閑暇狀態;f[i]=f[i+1]+1;

  如果當前時刻有任務,就掃一遍當前時刻開始的全部任務,看從他們中誰的結束時間轉移而來所收獲的閑暇最多;即? ? ?f[i]=max{f[i+task[++pos].endd]}。pos是我們記錄當前到第幾個任務的量,由于逆推,我們初始需要把任務按開始時間從大到小進行排序。

Code

1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace std; 5 6 int n,m,pos; 7 int f[20000],sum[20000]; 8 struct node{ 9 int beginn,endd; 10 }task[20000]; 11 12 bool cmp(node a,node b) 13 { 14 return a.beginn>b.beginn; 15 } 16 17 int main() 18 { 19 scanf("%d%d",&n,&m); 20 for(int i=1;i<=m;i++) 21 scanf("%d%d",&task[i].beginn,&task[i].endd),sum[task[i].beginn]++; 22 sort(task+1,task+1+m,cmp); 23 for(int i=n;i>=1;i--) 24 { 25 if(!sum[i]) f[i]=f[i+1]+1; 26 else 27 for(int j=1;j<=sum[i];j++) 28 f[i]=max(f[i],f[i+task[++pos].endd]); 29 } 30 printf("%d",f[1]); 31 return 0; 32 } View Code

?

轉載于:https://www.cnblogs.com/nopartyfoucaodong/p/9530802.html

總結

以上是生活随笔為你收集整理的Luogu P1280 Niko的任务【线性dp】By cellur925的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。