2018/7/8-纪中某C组题【jzoj1619,jzoj1620,jzoj1621,jzoj1622】
前言
分?jǐn)?shù)250250,十分開心
正題
T1:音樂節(jié)拍
洛谷題目鏈接:https://www.luogu.org/problemnew/show/P2969
大意
有n段音樂,每段音樂持續(xù)時(shí)間不同,q個(gè)詢問求一個(gè)時(shí)間點(diǎn)再放那首歌
考試時(shí)
開始時(shí)發(fā)現(xiàn)詢問的時(shí)間點(diǎn)不是按順序來的,于是就想到了離線算法。
解題思路
先將詢問排個(gè)序,然后一個(gè)指針指向現(xiàn)在的音樂,如果不是的話就往前推。
代碼
#include<cstdio> #include<algorithm> #define MN 50000 using namespace std; struct node{int num,que,ans; }qu[MN+1]; int n,q,b[MN+1]; bool cmp(node x,node y) {return x.que<y.que; } bool cmp2(node x,node y) {return x.num<y.num; } int main() {//freopen("mnotes.in","r",stdin);//freopen("mnotes.out","w",stdout);scanf("%d%d",&n,&q);for (int i=1;i<=n;i++)scanf("%d",&b[i]);for (int i=1;i<=q;i++){scanf("%d",&qu[i].que);qu[i].num=i;//標(biāo)記}sort(qu+1,qu+1+q,cmp);//排序int j=1,now=b[1]-1;//記錄現(xiàn)在位置for (int i=1;i<=q;i++){while (qu[i].que>now)//往前推{j++;now+=b[j];}qu[i].ans=j;//記錄}sort(qu+1,qu+1+q,cmp2);//排回原來的順序for (int i=1;i<=q;i++)printf("%d\n",qu[i].ans);//輸出 }T2:電視游戲問題
大意
洛谷鏈接:https://www.luogu.org/problemnew/show/P2967
有n個(gè)價(jià)格不同平臺(tái),上面有不同的游戲,每個(gè)游戲有不同的價(jià)格和價(jià)值,要求價(jià)格不超過v時(shí)價(jià)值最大。
考試時(shí)
開始就想到了,然后以為會(huì)超時(shí)就沒打
解題思路
用f[0][i]f[0][i]表示到現(xiàn)在并且買了這個(gè)平臺(tái)用了i元時(shí)最大價(jià)值
用f[1][i]f[1][i]表示到上次用了i元時(shí)最大價(jià)值
要將上一次繼承過來
f[0][i]=f[1][i?w]f[0][i]=f[1][i?w]
然后動(dòng)態(tài)轉(zhuǎn)移
f[0][i]=max{f[0][i?w]+c}f[0][i]=max{f[0][i?w]+c}
最后更新f[1]f[1]
f[1][j]=max{f[0][j]??,??f[1][j]}f[1][j]=max{f[0][j],f[1][j]}
代碼
#include<cstdio> #include<algorithm> using namespace std; int n,v,f[51][100001],w,c,k,wc; int main() {freopen("vidgame.in","r",stdin);freopen("vidgame.out","w",stdout);scanf("%d%d",&n,&v);for (int i=1;i<=n;i++){scanf("%d%d",&w,&k);for (int j=w;j<=v;j++)f[0][j]=f[1][j-w];//繼承上次for (int m=1;m<=k;m++){scanf("%d%d",&wc,&c);for (int j=v;j>=w+wc;j--)f[0][j]=max(f[0][j],f[0][j-wc]+c);//動(dòng)態(tài)轉(zhuǎn)移}for (int j=1;j<=v;j++)f[1][j]=max(f[0][j],f[1][j]),f[0][j]=0;//更新最大}printf("%d",f[1][v]); }T3:頭暈的奶牛
洛谷鏈接:https://www.luogu.org/problemnew/show/P2017
大意
一個(gè)n個(gè)點(diǎn)的圖,有m1條有向邊,有m2條無向邊,將無向邊變?yōu)橛邢蜻吺沟脠D變?yōu)橛邢驘o環(huán)圖。
考試時(shí)
有向無環(huán)圖,我就想到了拓?fù)渑判?#xff0c;然后就敲了一個(gè)東西發(fā)現(xiàn)不行。然后我就研究,發(fā)現(xiàn)可以將所有的點(diǎn)都集結(jié)在終點(diǎn)是出度為0的。然后打了一個(gè)奇怪的東西就80。
解題思路
先用有向邊建圖,然后再進(jìn)行拓?fù)渑判?#xff0c;之后一條無向邊的話就將拓?fù)湫蚺旁谇懊娴倪B排在后面的(因?yàn)橥負(fù)湫蚺旁诤竺娴臒o論如何也回不到前面)。
代碼
#include<cstdio> #include<algorithm> using namespace std; struct node{int to,next; }a[300001]; int n,m1,m2,x,y,ls[100001],in[100001],tot,head,tail,state[100001]; int d[100001],s,t,star,ta; void addl(int x,int y) {a[++tot].to=y;in[y]++;a[tot].next=ls[x];ls[x]=tot; } void bfs()//拓?fù)渑判?{do{x=state[++head];for (int i=ls[x];i;i=a[i].next){y=a[i].to;if (!d[y]){in[y]--;if (in[y]==0){state[++tail]=y;d[y]=++ta;}}}}while (head<tail); } int main() {//freopen("dizzy.in","r",stdin);//freopen("dizzy.out","w",stdout);scanf("%d%d%d",&n,&m1,&m2);for (int i=1;i<=m1;i++){scanf("%d%d",&x,&y);addl(x,y);}for (s=1;s<=n;s++)if (in[s]==0) state[++tail]=s,d[s]=++ta;//尋找起點(diǎn)bfs(),t++;for (int i=1;i<=m2;i++){scanf("%d%d",&x,&y);if (d[x]<d[y]) printf("%d %d\n",x,y);//判斷else printf("%d %d\n",y,x);} }T4:過路費(fèi)
洛谷:https://www.luogu.org/problemnew/show/P2966
大意
一個(gè)圖,一個(gè)點(diǎn)到另一個(gè)點(diǎn)的距離就是路徑邊權(quán)和加上路徑上的最大點(diǎn)值。
考試時(shí)
寫了一個(gè)spfa,然后發(fā)現(xiàn)一種情況
這時(shí)spfa就會(huì)走1?>2?>4?>51?>2?>4?>5代價(jià)11,可是如果走1?>3?>4?>51?>3?>4?>5的話代是價(jià)10。然后我就想到了一個(gè)方法:
用f[i][j]f[i][j]表示到達(dá)i點(diǎn)時(shí)路徑上最大點(diǎn)值的是j時(shí)的最短距離。
然后超時(shí)70分
解題思路
首先我們將點(diǎn)值進(jìn)行排序用num[i]num[i]表示點(diǎn)權(quán)從小到大排在第ii的點(diǎn)。然后枚舉kk時(shí)我們先從點(diǎn)權(quán)最小的點(diǎn)開始枚舉,然后
cost[i][j]=min{dis[i][j]+max{c[i],c[j],c[k]}}cost[i][j]=min{dis[i][j]+max{c[i],c[j],c[k]}}
排點(diǎn)權(quán)的目的是為了保證 max{c[i],c[j],c[k]}max{c[i],c[j],c[k]}中有里面最大的
代碼
#include<cstdio> #include<algorithm> #include<cstring> #define maxs(x,y,z) max(x,max(y,z)) using namespace std; int n,m,k,num[251],dis[251][251],cost[251][251],c[251],x,y,w; int main() {memset(dis,127/3,sizeof(dis));memset(cost,127/3,sizeof(cost));scanf("%d%d%d",&n,&m,&k);for (int i=1;i<=n;i++){num[i]=i;scanf("%d",&c[i]);}for (int i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&w);dis[x][y]=dis[y][x]=min(dis[x][y],w);//無向圖}for (int i=1;i<n;i++)for (int j=i+1;j<=n;j++)if (c[num[i]]>c[num[j]])swap(num[i],num[j]);//排序for (int q=1;q<=n;q++){int k=num[q];for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)if (i!=j&&i!=k&&j!=k){dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);cost[i][j]=min(cost[i][j],dis[i][j]+maxs(c[i],c[j],c[k]));//Floyd}}for (int i=1;i<=k;i++){scanf("%d%d",&x,&y);printf("%d\n",cost[x][y]);} }總結(jié)
以上是生活随笔為你收集整理的2018/7/8-纪中某C组题【jzoj1619,jzoj1620,jzoj1621,jzoj1622】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 头条文章如何段落首行缩进两个字符如何将正
- 下一篇: jzoj1029-电子眼【树形dp】