首页 > 代码库 > 【2016-09-27-DP小练】

【2016-09-27-DP小练】

得分250。。我真是个250。。。

犯了一些很搞笑的错。。

 

技术分享

f[i][j][k]表示第i个苹果,现在在j这个位置,还能用k次转移。

用i去更新i+1。

时间复杂度1000*2*30;

转移方程有个地方减一写错位了。。这么明显的错竟然没有看见。。50分TAT

技术分享
 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6  7 const int N=1100,M=50; 8 int n,K,f[N][3][M],t[N]; 9 10 int maxx(int x,int y){return x>y ? x:y;}11 void g(int &x,int y){x=maxx(x,y);}12 13 int main()14 {15     // freopen("a.in","r",stdin);16     freopen("bcatch.in","r",stdin);17     freopen("bcatch.out","w",stdout);18     scanf("%d%d",&n,&K);19     for(int i=1;i<=n;i++) scanf("%d",&t[i]),t[i]--;20     memset(f,-63,sizeof(f));21     f[0][0][K]=0;22     for(int i=0;i<n;i++)23     {24         int now=t[i+1];25         for(int k=0;k<=K;k++)26         {27             g(f[i+1][now][k],f[i][now][k]+1);28             if(k>=1) g(f[i+1][now][k-1],f[i][1-now][k]+1);29             g(f[i+1][1-now][k],f[i][1-now][k]);30             if(k>=1) g(f[i+1][1-now][k-1],f[i][1-now][k]);31         }32     }33     int ans=0;34     for(int k=0;k<=K;k++) ans=maxx(ans,maxx(f[n][0][k],f[n][1][k]));35     printf("%d\n",ans);36     return 0;37 }
T1

 

技术分享

f[i][j]表示当前时间为i,能力值为j时的最大滑雪次数。

预处理:给课程先排一次序;p[i]表示能力值为i时滑一次雪最少要多久。

然后就是要不去上课;要不去滑雪。

时间复杂度10^4*100。

技术分享
 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7  8 const int N=100010; 9 struct node{10     int c,d;11 }a[N];12 struct nod{13     int m,l,A;14 }b[N];15 int n,s,t,p[N],f[11000][110],mx[N];16 17 // bool cmp1(node x,node y)18 // {19     // if(x.c==y.c) return x.d<y.d;20     // return x.c<y.c;21 // }22 23 bool cmp2(nod x,nod y){return x.m<y.m;}24 int maxx(int x,int y){return x>y ? x:y;}25 int minn(int x,int y){return x<y ? x:y;}26 void g(int &x,int y){x=maxx(x,y);}27 28 int main()29 {30     // freopen("a.in","r",stdin);31     freopen("ski.in","r",stdin);32     freopen("ski.out","w",stdout);33     scanf("%d%d%d",&t,&s,&n);34     memset(p,63,sizeof(p));35     for(int i=1;i<=s;i++)36     {37         scanf("%d%d%d",&b[i].m,&b[i].l,&b[i].A);38     }39     for(int i=1;i<=n;i++)40     {41         scanf("%d%d",&a[i].c,&a[i].d);42         p[a[i].c]=minn(p[a[i].c],a[i].d);43     }44     for(int i=1;i<=100;i++) p[i]=minn(p[i],p[i-1]);45     // sort(a+1,a+1+n,cmp1);46     sort(b+1,b+1+s,cmp2);47     b[s+1].m=0;48     int ind=1,ans=0;49     memset(f,-63,sizeof(f));50     memset(mx,-63,sizeof(mx));51     f[0][1]=0;52     for(int i=0;i<=t;i++)53         for(int j=1;j<=100;j++)54         {55             g(f[i][j],mx[j]);56             while(b[ind].m<i && ind<=s) ind++;57             if(b[ind].m==i) g(f[i+b[ind].l][b[ind].A],f[i][j]);58             g(f[i+p[j]][j],f[i][j]+1);59             g(mx[j],f[i][j]);60             if(i==t) ans=maxx(ans,f[i][j]); 61         }62     printf("%d\n",ans);63     return 0;64 }
T2

 

技术分享

这题是我被卡住的一题。。因为我一直在想它为了达到后面的限制,前面可能要特意往下走一点。。

一出来发现自己好搞笑。。

首先我们从后往前预处理一遍,s[i]=minn(s[i],s[i+1]+dis(i~i+1)),这样就保证了满足当前的限制,以后的限制就一定有办法达到!

然后就是一个贪心了。

对于当前的v,下一个限制s[i+1],它们之间的速度差k=s[i+1]-v,距离d=dis(i~i+1)

设加速x秒,减速y秒。

x+y=d

x - y=k

所以最高速度x=(d+k)/2;

ans取max。

技术分享
 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7  8 const int N=110000; 9 int l,n,pl,t[N],s[N];10 struct node{11     int t,s;12 }a[N];13 14 bool cmp(node x,node y){return x.t<y.t;}15 int maxx(int x,int y){return x>y ? x:y;}16 int minn(int x,int y){return x<y ? x:y;}17 18 int main()19 {20     // freopen("a.in","r",stdin);21     freopen("bobsled.in","r",stdin);22     freopen("bobsled.out","w",stdout);23     scanf("%d%d",&l,&n);24     pl=0;t[0]=0;25     for(int i=1;i<=n;i++) scanf("%d%d",&a[i].t,&a[i].s);26     sort(a+1,a+1+n,cmp);27     for(int i=n;i>=1;i--)28     {29         int d=a[i].t-a[i-1].t;30         a[i-1].s=minn(a[i-1].s,a[i].s+d);31     }32     int v=1,ans=0;33     for(int i=1;i<=n;i++)34     {35         int d=a[i].t-a[i-1].t;36         if(v+d<=a[i].s) v=v+d,ans=maxx(ans,v);37         else 38         {39             int k=a[i].s-v;40             ans=maxx(ans,v+(d+k)/2);41             v=a[i].s;42         }43         // printf("v = %d\n",v);44     }45     ans=maxx(ans,v+l-a[n].t);46     printf("%d\n",ans);47     return 0;48 }
T3

 

技术分享

f[i][j]表示当前扫到第i只奶牛,余数是j。

转移方程就直接看把。。

技术分享
 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7  8 const int N=2100,M=1100,Mod=(int)1e8; 9 int n,m,f[N][M],a[N];10 11 int maxx(int x,int y){return x>y ? x:y;}12 void g(int &x,int y){x=(x+y)%Mod;}13 14 int main()15 {16     // freopen("a.in","r",stdin);17     freopen("fristeam.in","r",stdin);18     freopen("fristeam.out","w",stdout);19     scanf("%d%d",&n,&m);20     for(int i=1;i<=n;i++) scanf("%d",&a[i]);21     memset(f,0,sizeof(f));22     f[0][0]=1;23     for(int i=0;i<=n;i++)24     {25         for(int j=0;j<=m;j++)26         {27             g(f[i+1][(j+a[i+1])%m],f[i][j]);28             g(f[i+1][j],f[i][j]);29             // printf("f [ %d ] [ %d ] = %d\n",i,j,f[i][j]);30         }31     }32     printf("%d\n",f[n][0]-1);33     return 0;34 }
T4

 

【2016-09-27-DP小练】