题目描述
“关关雎鸠,在河之洲。窈窕淑女,君子好逑。”——《诗经》
T博士的大儿子阿T(阿嚏?)最近遇到了一件麻烦事。
有n个MM同时邀请阿T在8月14日上午11:30拜访她们家,可那时阿T刚比赛完,所以不能先提前拜访几个,而他又不会分身术,所以他只得分别拜访。他共有T分钟的时间可以用于拜访MM。他还安排好了拜访的顺序,对于每个MM都可以选择拜访或不拜访。对于要拜访的MM必须按阿T安排好的顺序拜访。
对于每个MM都有如下数据:
不高兴系数x,为2到9的整数。
不高兴度X,若阿T迟到t分钟到她家,则X=x^t(x的t次方);若阿T不拜访她家,则X=x^T。
拜访时间y(分钟),保证0<yi<=T,即阿T在她家停留的时间,若阿T在到了她家但停留时间不足y分钟,她的不高兴度就会变成正无穷大。
假设阿T从一个地方到另一个地方不用消耗时间,阿T希望在有限的T分钟里使所有MM的不高兴度之和最小。请告诉他这个最小值是多少。输入
第一行是两个正整数n和T。
第1+i(1<=i<=n)有两个正整数xi和yi,分别是阿T安排的拜访顺序中第i个MM的不高兴系数和拜访时间。输出
请只输出一行,仅一个正整数,为最小的不高兴度之和。
数据范围限制
对于20%的数据,满足1<=n<=10,1<=T<=9;
对于50%的数据,满足1<=n<=20,1<=T<=30;
对于100%的数据,满足1<=n<=20,1<=T<=180;提示
【样例输入2】
2 30
5 16
2 16
【样例输出2】
1073741825
(只拜访第一个MM,到她家时迟到了0分钟,不高兴度之和为5^0+2^30;若只拜访第二个MM,则不高兴度之和为2^0+5^30,显然较大)
我们需关注一条信息:对于要拜访的MM,必须按阿T安排好的顺序拜访。这个条件保证了问题的“无后效性”,因此考虑用动态规划做题。我们可以以已处理完的MM个数为阶段,以时间为附加维度,定义数组f[i(前i个MM)][t(前t分钟)]。对于每一个阶段,如果t<T,说明前t分钟时间不够拜访这个MM,只能在同一时间之前MM的不高兴度之和的最小值中加上x^T。如果t>=T,有时间去这个MM家里玩啦,那我们计算一下,是不拜访她得到的结果较优呢,还是拜访她,但把之前拜访MM的时间让出拜访她所需的时间得到的结果较优呢,于是就能得到状态转移方程了(在下面我给出的程序里)。
由于不高兴度是乘方形式的,指数很大,后80%的数据得用高精度解决。高精度实现代码难度较高,但思维难度较低,这里不做详细介绍。总结发现,这题是简单动态规划和高精度套餐的结合,和01背包问题及其相似,所以先做01背包问题再做这道题,难度会减小很多。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct supernumber{int d[1001];int l;supernumber(){memset(d,0,sizeof(d));l=0;}
}f[21][201],point,answer;
int base[21],Time[21];
int n,total;
supernumber mul(int x,supernumber y)
{int temp,carry=0;for(int i=1;i<=y.l;i++){temp=x*y.d[i]+carry;carry=temp/10;y.d[i]=temp%10;}while(temp){y.d[y.l++]=temp%10;temp/=10;}y.l--;return y;
}
supernumber add(supernumber x,supernumber y)
{supernumber z;int carry=0;z.l=max(x.l,y.l)+1;for(int i=1;i<=z.l;i++){z.d[i]=x.d[i]+y.d[i]+carry;carry=z.d[i]/10;z.d[i]%=10;}while(!z.d[z.l]) z.l--;return z;
}
supernumber com(supernumber x,supernumber y)
{if(x.l>y.l) return y;if(x.l<y.l) return x;if(x.l==y.l){int p=x.l;while(x.d[p]==y.d[p]&&p)p--;if(!p) return x;if(x.d[p]>y.d[p]) return y;if(x.d[p]<y.d[p]) return x;}
}
int main()
{freopen("girls.in","r",stdin);freopen("girls.out","w",stdout);cin>>n>>total;for(int i=1;i<=n;i++)cin>>base[i]>>Time[i];for(int i=0;i<=n;i++)for(int j=0;j<=total;j++)f[i][j].d[200]=1,f[i][j].l=200;f[0][0].d[200]=f[0][0].l=0;for(int i=1;i<=n;i++) for(int j=0;j<=total;j++){memset(point.d,0,sizeof(point.d));point.d[1]=point.l=1;for(int k=1;k<=total;k++)point=mul(base[i],point);f[i][j]=add(f[i-1][j],point);if(j>=Time[i]){memset(point.d,0,sizeof(point.d));point.d[1]=point.l=1;for(int k=1;k<=j-Time[i];k++)point=mul(base[i],point);f[i][j]=com(f[i][j],add(f[i-1][j-Time[i]],point));}}answer.d[200]=1;answer.l=200;for(int i=1;i<=total;i++)answer=com(answer,f[n][i]);for(int i=answer.l;i>=1;i--)cout<<answer.d[i];
}
本文发布于:2024-02-02 01:42:34,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170681345840602.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |