东北农业大学部分题解

我国现在能源消耗非常严重,现在政府有这样一个工作,每天早上都需要把一些路灯关掉,但是他们想让在关闭的过程中所消耗的能源是最少的,负责路灯关闭的工作人员以1m/s的速度进行行走,假设关闭路灯的时候不需要花费任何的时间,请你编写一个程序,计算在给定路灯位置和每个路灯的消耗能源的多少,求出当所有路灯关闭的时候所需要的最少能量

输入描述:

多组测试数据循环输入
每组测试数据第一行:N表示路灯的数量 (2<=N <=1000)
第二行:V表示开始关灯的路灯号码。 (1<=V<=N)
接下来的N行中,每行包含两个用空格隔开的整数D和W,用来描述每盏灯的参数
D表示该路灯到原点的距离 (用米为单位来表示),
W表示灯泡的功率,即每秒该灯泡所消耗的能量数。(0<=D<=1000,0<=W<=1000)
路灯按照顺序给出,起始位置的那盏灯不算消耗的电能里面

输出描述:

输出一个整数,即消耗能量之和的最小值。
示例1

输入

4
3
2 2
5 8
6 1
8 7

输出

56

说明

对于样例,我一开始在第三个路灯的位置,即在6位置
第1s的时候去5把第二盏灯关闭,消耗电能8
然后去第四盏灯,第四盏灯亮的时间是4s 所以消耗电能28
最后去关第一盏灯第一盏灯亮的时间是10s 所以消耗电能20
最后总和为8+28+20=56

考虑到 [i,j]区间 只能由[i+1,j]和[i,j-1]这两个区间而来,然后dp一下就行了,然后dp[i][j]表示目前在j,dp[j][i]表示目前在i
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e3+88; 
long long dp[N][N];
int n,D[N],W[N],m;
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
    for(int i=1;i<=n;++i) scanf("%d%d",D+i,W+i);
    for(int i=1;i<=n;++i) for(int j=1;j<=n;++j)
    dp[i][j]=1LL<<60;
    for(int i=1;i<=n;++i) W[i]=W[i]+W[i-1];
    dp[m][m]=0;
    for(int i=m;i;--i) for(int j=m;j<=n;++j) {
        dp[i][j]=min(dp[i][j],dp[i][j-1]+1LL*(D[j]-D[j-1])*(W[n]-W[j-1]+W[i-1]));
        dp[i][j]=min(dp[i][j],dp[j-1][i]+1LL*(D[j]-D[i])*(W[n]-W[j-1]+W[i-1]));
        dp[j][i]=min(dp[j][i],dp[j][i+1]+1LL*(D[i+1]-D[i])*(W[n]-W[j]+W[i]));
        dp[j][i]=min(dp[j][i],dp[i+1][j]+1LL*(D[j]-D[i])*(W[n]-W[j]+W[i]));
    }
    printf("%lld\n",min(dp[1][n],dp[n][1]));
    }
}

wyh非常喜欢lol游戏,一天,他听说学校要选拔lol队员,他非常高兴的就去了,选拔规则是,一共有N个评委,每个评委根据线上对线能力和打团能力给出一个[0,M]之间的一个整数作为分数,然后取平均值,wyh学长非常好奇,他想知道有多少种这样的情况:

平均分等于其中某一位评委给的分数

例如2个评委,给打的分数都是1分,那么此时平均分是1分,即等于第一个评委的分数,又等于第二个评委的分数,这样答案是2

但是由于每个评委打的分都是在[0,M]之间,所以会有很多种情况。

现在请你帮助你们wyh学长数一下有多少种这样的情况,由于结果会很大,请你对1000000007取余

输入描述:

输入第一行一个整数T(1<=T<=110)
接下来有T组测试数据,对于每组测试数据输入2个数n和M(2<=n<=60,1<=M<=200),代表有n个评委,每个评委的分数都在[0,M]之间的一个整数

输出描述:

对于每组测试数据,输出对应答案
示例1

输入

1
3 1

输出

6

说明

 

样例解释:

对于样例有以下几种打分情况是符合要求的

 

 


 

其中每种情况相等的可能性都是三个,比如0分的时候,平均分和第一位、第二位、第三位都相等,所以是3中情况,1的时候也同理,所以答案为6

 

dp[i][j]表示i个人拿j分有几种方式,然后算到n-1,枚举最后一个人即为n*dp[n-1][符合要求的]

如果枚举不同的最后一个人,所得到的分数序列一样也没关系,因为他是每个序列中=平均分的人的和,问题本身就包含了重复。

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int P=1e9+7;
int n,m,T,dp[2][12006];
int main(){
    for(scanf("%d",&T);T--;){
        scanf("%d%d",&n,&m);
        memset(dp,0,sizeof(dp));
        for(int i=0;i<=m;++i) dp[0][i]=1;
        int now=1;
        for(int i=1;i<n;++i) {
            for(int j=0;j<=i*m;++j) {
                if(j<=m) dp[now][j]=dp[now^1][j];
                else dp[now][j]=(dp[now^1][j]-dp[now^1][j-m-1]+P)%P;
            }
            if(i!=n-1) for(int j=1;j<=(i+1)*m;++j) dp[now][j]=(dp[now][j]+dp[now][j-1])%P;
            now^=1;
        }
        int ans=0;
        for(int i=0;i<=m;i++) ans=(ans+dp[now^1][(n-1)*i])%P;
        ans=1LL*ans*n%P;
        printf("%d\n",ans);
    }
}

一天,你们wyh学长和你们zhl学长玩一个游戏,这个游戏规则是这样的

给你n个城市,保证这n个城市之间都只有一条道路可以到达。

有一件物品,在所有城市中都是一样的,但是由于各个城市的经济发展不同,导致每个城市对于这件物品销售的价格不同。

游戏一共进行Q轮。

每轮给你2个点s和t,其中s代表起点,t代表终点。

对于每一个城市都可以选择买这个物品,如果手里有这个物品的话,也可以选择卖掉这个物品,对于同一个城市来说,买和卖的价格是一样的,每一个城市只能买一件物品

现在,你们wyh学长和zhl学长都需要找到一个方案,使得从起点走到终点的时候盈利最多,请你帮助帮助他们吧

输入描述:

每个测试文件中都只有一组测试数据

输入第一行一个整数n(1<=n<=50000),代表有n个城市

第二行输入n个数,代表每个城市对于这件物品的价格wi(1<=wi<=50000)

接下来有n-1行,每行2个数a和b,代表a到b之间有一条路

接下来输入一个数Q(1<=Q<=50000)

接下来Q行,每行2个数s和t

输出描述:

对于每组测试数据,输出对应答案,如果从起点到终点不能盈利的话,输出0
示例1

输入

4
1 
5 
3 
2
1 3
3 2
3 4
9
1 2
1 3
1 4
2 3
2 1
2 4
3 1
3 2
3 4

输出

4
2
2
0
0
0
0
2
0

离线dfs;
对问题进行分类
https://blog.csdn.net/sdj222555/article/details/43003179 看这个博客

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5e4+88;
vector<int>G[N],Q[N],dir[N],st[N],ed[N],pos[N];
int m,F[N],ans[N],mx[N],mi[N],up[N],down[N],n,W[N];
bool vis[N];
int find(int x){
    if(F[x]==x) return x;
    int t=find(F[x]);
    
    up[x]=max(max(up[x],up[F[x]]),mx[F[x]]-mi[x]);
    down[x]=max(max(down[x],down[F[x]]),mx[x]-mi[F[x]]);
    mi[x]=min(mi[F[x]],mi[x]);
    mx[x]=max(mx[F[x]],mx[x]);
    
    return F[x]=t;
}
void dfs(int u){
    vis[u]=1;
    for(int i=0;i<(int)Q[u].size();++i) {
        int v=Q[u][i];
        if(vis[v]) {
            int t=find(v),z=dir[u][i];
            if(z>0) {
                st[t].push_back(u);
                ed[t].push_back(v);
                pos[t].push_back(z);
            }
            else {
                st[t].push_back(v);
                ed[t].push_back(u);
                pos[t].push_back(-z);
            }
        }
    }
    for(int i=0;i<(int)G[u].size();++i) if(!vis[G[u][i]])
    dfs(G[u][i]),F[G[u][i]]=u;
    for(int i=0;i<(int)st[u].size();++i) {
        int x=st[u][i],y=ed[u][i],z=pos[u][i];
        find(x);find(y);
        ans[z]=max(mx[y]-mi[x],max(up[x],down[y]));
    }
}
int main(){
    int x,y;
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%d",W+i);
    for(int i=1;i<=n;++i) F[i]=i,mx[i]=mi[i]=W[i];
    for(int i=1;i<n;++i) {
        scanf("%d%d",&x,&y);
        G[x].push_back(y);
        G[y].push_back(x);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;++i) {
        scanf("%d%d",&x,&y);
        Q[x].push_back(y);
        dir[x].push_back(i);
        Q[y].push_back(x);
        dir[y].push_back(-i);
    }
    dfs(1);
    for(int i=1;i<=m;++i) printf("%d\n",ans[i]);
}

 



posted @ 2018-04-12 23:25  Billyshuai  阅读(249)  评论(0编辑  收藏  举报