2018 BUPT Winter Training #7 Div.2

11 篇文章 0 订阅
11 篇文章 0 订阅

A - Vacations

对不起,这题我写过hh,ctrl+c完事。DP一下就行了。

#include <cstdio>
#include <algorithm>
using namespace std;
int dp[105][3]={0};
int main(){
    int n,toda;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&toda);
        if(toda==3){
            dp[i][2]=max(dp[i-1][1],dp[i-1][0])+1;
            dp[i][1]=max(dp[i-1][2],dp[i-1][0])+1;
            dp[i][0]=max(dp[i-1][0],max(dp[i-1][1],dp[i-1][2]));
        }else if(toda==2){
            dp[i][0]=dp[i][2]=dp[i][0]=max(dp[i-1][0],max(dp[i-1][1],dp[i-1][2]));
            dp[i][1]=max(dp[i-1][2],dp[i-1][0])+1;
        }else if(toda==1){
            dp[i][0]=dp[i][1]=dp[i][0]=max(dp[i-1][0],max(dp[i-1][1],dp[i-1][2]));
            dp[i][2]=max(dp[i-1][1],dp[i-1][0])+1;
        }else dp[i][0]=dp[i][1]=dp[i][2]=dp[i][0]=max(dp[i-1][0],max(dp[i-1][1],dp[i-1][2]));
    }
    printf("%d",n-max(dp[n][0],max(dp[n][1],dp[n][2])));
}

B - Tourist’s Notes

判断相邻两天之间的最高距离以及有没有可能到达即可。

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
#define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++)
#define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--)
using namespace std;
int d[100005]={0},h[100005]={0};
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    FF(i,1,m)scanf("%d%d",&d[i],&h[i]);
    int mmax=max(d[1]-1+h[1],n-d[m]+h[m]),tmax,delta;
    FS(i,m,1)d[i]-=d[i-1];
    FF(i,2,m){
        if((delta=abs(h[i]-h[i-1]))>d[i]){
            puts("IMPOSSIBLE");
            return 0;
        }
        if(mmax<(tmax=((d[i]-delta)>>1)+max(h[i],h[i-1])))mmax=tmax;
    }
    printf("%d\n",mmax);
}

C - Dreamoon and WiFi

先用杨辉三角求出组合数,然后就完事了。

#include <cstdio>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
#define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++)
#define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--)
char s1[15],s2[15];
int c[15][15]={0};
int main(){
    c[0][1]=1;
    FF(i,1,12)FF(j,1,i)c[i][j]=c[i-1][j]+c[i-1][j-1];
    int ss1=0,ss2=0,ws2=0;
    scanf("%s%s",s1,s2);
    for(int i=0;s1[i];i++)if(s1[i]=='+')ss1++;else ss1--;
    for(int i=0;s2[i];i++)if(s2[i]=='+')ss2++;else if(s2[i]=='-')ss2--;
    else ws2++;
    int s=ss1-ss2;if(s<0)s=-s;
    int p=0;
    while(p<=ws2)if(2*p-ws2==s)break;else p++;
    if(2*p-ws2!=s)printf("%.12lf",0);
    else printf("%.12lf",(double)(c[ws2+1][p+1])/(1<<ws2));
}

D - Maximum Increase

最长连续上升子段…不讲了。

#include <cstdio>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
#define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++)
#define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--)
int a[100005];
int main(){
    a[0]=1000000001;
    int n,maxcnt=0,cnt=0;
    scanf("%d",&n);
    FF(i,1,n)scanf("%d",&a[i]);
    FF(i,1,n)if(a[i]<=a[i-1]){
        if(maxcnt<cnt)maxcnt=cnt;
        cnt=1;
    }else cnt++;
    printf("%d",maxcnt<cnt?cnt:maxcnt); 
} 

E - Fence

求连续k个元素的最小值

#include <cstdio>
#include <cstring>
#define MO 1061109567
#define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++)
using namespace std;
int sum[150005]={0};
int main() {
    int n,k,mmin,mini,tmin;
    while(~scanf("%d%d",&n,&k)){
        FF(i,1,n){
            scanf("%d",&sum[i]);
            sum[i]+=sum[i-1];
        }
        mmin=MO;
        FF(i,1,n-k+1){
            if(mmin>(tmin=sum[i+k-1]-sum[i-1]))mmin=tmin,mini=i;
        }
        printf("%d\n",mini);
    }
}

F - Financiers Game

dfs+dp记忆化搜索。手算一下dp能够承受,于是dfs就有了基础。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <utility>
#define MO 1061109567
#define MP make_pair
#define sec second
#define fir first
#define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++)
#define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--)
using namespace std;
typedef pair<int,int> pii;
int dp[2][100][2050][200];
bool u[2][100][2050][200];
pii tem;
int s[4005]={0},n;
int dfs(int l,int r,int k,int step){
    int t=step&1;
    if(u[t][k][l][n-r+l])return dp[t][k][l][n-r+l];
    u[t][k][l][n-r+l]=1;
    if(r-l+1<k)return dp[t][k][l][n-r+l]=0;
    if(t){
        if(r-l+1==k)return dp[t][k][l][n-r+l]=-s[r]+s[l-1];
        return dp[t][k][l][n-r+l]=min(dfs(l,r-k,k,step+1)+s[r-k],dfs(l,r-k-1,k+1,step+1)+s[r-k-1])-s[r];
    }
    if(r-l+1==k)return dp[t][k][l][n-r+l]=s[r]-s[l-1];
    return dp[t][k][l][n-r+l]=max(dfs(l+k,r,k,step+1)+s[l+k-1],dfs(l+k+1,r,k+1,step+1)+s[l+k])-s[l-1];
}
int main() {
    scanf("%d",&n);
    FF(i,1,n)scanf("%d",&s[i]);
    FF(i,1,n)s[i]+=s[i-1];
    printf("%d\n",dfs(1,n,1,0));
}

I - Tower of Hanoi

求带权最小代价的汉诺塔移动。依然dfs+dp搜索.

#include <cstdio>
#include <algorithm>
#define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++)
#define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--)
using namespace std;
typedef long long ll;
ll dp[4][4][50]={0L},t[5][5]={0L};
bool dped[4][4][50]={0};
ll move(int n,int from,int thr,int to){
    if(dped[from][to][n])return dp[from][to][n];
    dped[from][to][n]=1L;
    if(n==0)return dp[from][to][n]=0L;
    return dp[from][to][n]=min(move(n-1,from,to,thr)+t[from][to]+move(n-1,thr,from,to),(move(n-1,from,thr,to)<<1)+t[from][thr]+t[thr][to]+move(n-1,to,thr,from));
}
int main() {
    FF(i,1,3)FF(j,1,3)scanf("%I64d",&t[i][j]);
    int n;
    scanf("%d",&n);
    printf("%I64d",move(n,1,2,3));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值