20171029模拟赛

    LGL帮n个人买东西,有m个物品给他选择。每件物品有一个价格c[i]和美丽度d[i]。每一个人都只需要买一个物品,但是他们都很挑剔并且奢侈,第i个人需要买的东西的价格大等于a[i],美丽度大等于b[i]。每个物品只能买给一个人,请问LGL最少要花多少钱?如果无法全部满足,输出-1。

 

输入格式:

第一行为两个整数n、m,接下来的n行每行两个整数a[i]、b[i],再接下来的m行每行两个整数c[i]、d[i]。

 

输出格式:

一个整数,表示LGL最少花钱数。

 

样例输入

样例输出

4 7
1 1
2 3
1 4
4 2
3 2
2 1
4 3
5 2
5 4
2 6
4 4

12

 

样例解释:

物品

1

2

2

3

3

6

4

7

 

 

数据范围:

对于100%的数据:1<=n、m<=100000,1<=其他数字<=109

 

 set大法好

考虑贪心,将物品和要求都按美丽度从大到小排序,接着按照人的顺序做:

加入一个新的人时,把所有美丽度能满足他的要求的物品加入一个按价格排序的set里,然后寻找set中价格能满足他的要求的物品中价格最低的物品。

如果没有就输出-1,有的话ans加上它,然后将它从set中删去。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
inline int read(){
    int t=1,num=0;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();}
    while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();}
    return num*t;
}
const int N=100010;
struct goods{int c,v;}a[N],b[N];
multiset<int> s;
multiset<int>::iterator it;
int n,m;long long ans;
bool cmp(goods a,goods b){return a.v>b.v;}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)a[i].c=read(),a[i].v=read();
    for(int i=1;i<=m;i++)b[i].c=read(),b[i].v=read();
    sort(a+1,a+1+n,cmp);sort(b+1,b+1+m,cmp);
    int i,j=1;
    for(i=1;i<=n;i++){
        while(j<=m&&a[i].v<=b[j].v)s.insert(b[j++].c);
        it=s.lower_bound(a[i].c);
        if(it==s.end()){
            puts("-1");return 0;
        }
        ans+=*it;s.erase(it);
    }
    printf("%lld",ans);
    return 0;
}
View Code

 

加密

    LGL找了n个人来加密一个含有n个数字的密码。他的方法是:找n个人记住每一个数字c[i],然后每个人计算其他人的数字之和mod 98765431作为加密后的密码。但是ditoly只用了5秒钟就算出了他的密码,这让他十分气馁。于是他要用更高级的加密方式:即做上述过程x次。LGL想看看ditoly现在要多少秒才能算出来,所以他请你帮他算出加密后的n个数字。

 

输入格式:

第一行为两个整数n、x,接下来n行每行一个整数c[i]。

 

输出格式:

n行,每行一个整数,表示加密后的每一个数。

 

样例输入

样例输出

3 4
1
0
4

26
25
29

 

样例解释:

    算就是了。

 

数据范围:

对于100%的数据:1<=n<=50000,1<=x<=1414213562,1<=c[i]<=90000000。

 

题解: 设sum=sum{a[i]},只要想到下一个a[i]=sum-a[i],下一个sum=(n-1)*sum就是矩阵乘法裸题。

我的作法与题解稍有不同但也是矩阵乘法。矩阵见代码

#include<cstdio>
#include<cstring>
#include<iostream>
#define For(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
using namespace std;
const int mod=98765431;
struct Yzyet{ll p[2][2];}ans,tmp;
ll x,sum=0;int q[50010],n;
inline Yzyet operator *(const Yzyet a,const Yzyet b){
    Yzyet c;memset(c.p,0,sizeof(c.p));
    For(i,0,1)For(k,0,1)
        if(a.p[i][k])For(j,0,1)
        c.p[i][j]=((c.p[i][j]+a.p[i][k]*b.p[k][j])%mod+mod)%mod;
    return c;
}
void init(){
    ans.p[0][0]=0;ans.p[0][1]=1;ans.p[1][0]=ans.p[1][1]=0;
    tmp.p[0][0]=n-1;tmp.p[0][1]=0;tmp.p[1][0]=1;tmp.p[1][1]=-1;
}
void ksm(ll t){
    while(t){
        if(t&1)ans=ans*tmp;
        tmp=tmp*tmp; t>>=1;
    }
}
int main()
{
    freopen("password.in","r",stdin);
    freopen("password.out","w",stdout);
    scanf("%d%lld",&n,&x);init();ksm(x);
    for(int i=1;i<=n;i++){
        scanf("%d",&q[i]);sum=(sum+q[i])%mod;
    }
    for(int i=1;i<=n;i++){
        int t=(x&1?-1:1)*q[i];
        printf("%d\n",(((sum*ans.p[0][0])%mod+t)%mod+mod)%mod);
    }
    return 0;
}
View Code

 

花费

LGL进入他的豪宅需要密码。他的密码长度为m,并且由n个不同字母构成。现在他想把密码改成回文的,他可以在任意位置添加或删除字母,而第i个字母都有不同的添加花费a[i]和删除花费b[i]。请问LGL最少要花多少钱才能把密码改成回文的?

 

输入格式:

第一行为两个整数n、m,接下来的n行每行一个字母和两个数a[i]和b[i],表示该字母的添加花费和删除花费。

 

输出格式:

一个整数,表示最小花费。

 

样例输入

样例输出

3 4
abcb
a 1000 1100
b 350 700
c 200 800

900

 

样例解释:

           变成了bcbabcb。

 

数据范围:

对于100%的数据:1<=m<=2000、1<=n<=26,0<=a[i]、b[i]<=10000。

 

首先加一个字母和删一个字母其实是一样的,所以处理一个字母的花费就是min{a[i],b[i]}。接着直接区间dp即可。

#include<cstdio>
int f[2010][2010];
int n,m,w[26];
char s[2010],c[5];
int min(int a,int b){return a<b?a:b;}
int main()
{
    freopen("cost.in","r",stdin);
    freopen("cost.out","w",stdout);
    scanf("%d%d",&m,&n);
    scanf("%s",s+1);
    for(int i=1;i<=m;i++){
        int a,b;scanf("%s%d%d",c,&a,&b);
        w[c[0]-'a']=min(a,b);
    }
    for(int l=2;l<=n;l++){
        for(int i=1;i+l-1<=n;i++){
            int j=i+l-1;
            f[i][j]=min(f[i][j-1]+w[s[j]-'a'],f[i+1][j]+w[s[i]-'a']);
            if(s[i]==s[j])f[i][j]=min(f[i][j],f[i+1][j-1]);
        }
    }
    printf("%d\n",f[1][n]);
    return 0;
}
View Code

本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。

转载于:https://www.cnblogs.com/Yzyet/p/7875564.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值