您的位置:首页 > 其它

151021 总结

2015-10-23 08:02 323 查看
T1 模拟题,给单调队列优化dp跪了,没特判所以95

T2

我看到这个题的想法是动态规划,然后设计状态dp[i] 表示到第i个点的时候做出合法解的最小代价,其中第i个点是离散化后的点,发现状态转移是很显然的:

Dp[i]= min (j= 1—> i-1)(k=1—>j)dp[ j]+w[i,k]可以发现对于每个相同的w,我们考虑他对答案的影响,那么只需要求出k到i-1之间dp值的最小值,那么就把dp值做进线段树里,枚举右区间,枚举所选的区间,线段树查询,这就做完了。时间复杂度O(m*logm)

考场上没时间所以输出-1骗了95

T3

首先是下面10*10的矩阵,floyd可以判断多源图集的联通性,放到这里非常方便

对于w[1],w[2],w[3]…..w
,题目要求必须为不下降序列,由于正向考虑非常不方便(因为要越来越大可能会产生矛盾),我们可以倒着考虑。从w
开始,建立一个不上升子序列,这个时候可以发现当前数当然越大越好,所以可以很好地运用贪心:让当前数在满足当前情况下取最大值。

令w[i]为当前状态的限制,f[i]为当前当前状态的最大值,这个时候分为3种情况

1,w[i]的位数大于f[i],贪心的将每一位f[i]变为最大即可(因为再怎么改也不会超过w[i])

2. w[i]的位数小于f[i],直接输出NO

3,w[i]的位数等于f[i],又要分情况讨论:

{

1. 举个例子,当前限制为4567,我们可以在第一位最大取4,第二位最大取5…..

2. 再举个例子,比如限制为3000,我们可以在第一位取3,然而如果我们不能在第2,3,4位同时取0,那么第一位取3是完全没有意义的,所以第一位最大能取2

3. 再举个例子,比如当前限制为3000,我们确定了第一位为2,那么后面的数完全没有必要取0。(可以取任意数)

}

关于这种情况,我觉得dfs来实现是个很不错的方法。

另外,这道题需要高精度。

考场上写的很崩溃,最后还是AC了

//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
inline void R(int &v)
{
v=0;char c=0;
while(c<'0' || c>'9')c=getchar();
while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
}
int n,h;
int a[1000010];
int main()
{
freopen("jump.in","r",stdin);
freopen("jump.out","w",stdout);
R(n),R(h);
for(int i=1;i<=n;i++)
{
R(a[i]);
}
sort(a+1,a+n+1);
a[++n]=2147483647;
int nowhigh=0,minn=0,maxx=0;
for(int i=0;i<=n;i++)
{
if(a[i+1]>a[i]+h)
{
printf("%d %d %d\n",a[i],maxx,minn);
//cerr<<clock()<<endl;
return 0;
}
if(a[i+1]-nowhigh>h)nowhigh=a[i],minn++;
maxx++;
}
}


//Copyright(c)2015 liuchenrui
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<vector>
#define ll long long
using namespace std;
map <ll,ll> p;
vector <ll> q[200010],d[200010];
struct node{ll val;
};node tree[600010];
ll n,m,f[200010];
struct zb{ll l;ll r;ll c;
};zb a[100010];
ll Ra[200010],tot=0;
void work(ll now,ll x,ll y,ll s,ll z)
{
if(x==y)
{
tree[now].val=min(tree[now].val,z);
return ;
}
ll mid=(x+y)/2;
if(s<=mid) work(now<<1,x,mid,s,z);
if(s>mid) work(now<<1|1,mid+1,y,s,z);
tree[now].val=min(tree[now<<1].val,tree[now<<1|1].val);
}
ll change(ll now,ll x,ll y,ll l,ll r)
{
ll ret=(ll)1e15;
if(x>=l&&y<=r)
return tree[now].val;
ll mid=(x+y)/2;
if(l<=mid) ret=min(ret,change(now<<1,x,mid,l,r));
if(r>mid) ret=min(ret,change(now<<1|1,mid+1,y,l,r));
return ret;
}
int main()
{
freopen("proof.in","r",stdin);
freopen("proof.out","w",stdout);
scanf("%d%d",&n,&m);
for(ll i=1;i<=m;i++)
{
scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].c);
Ra[++tot]=a[i].l;
Ra[++tot]=a[i].r;
}
sort(Ra+1,Ra+tot+1);
unique(Ra+1,Ra+tot+1);
for(ll i=1;i<tot;i++)
if(Ra[i]>=Ra[i+1])
tot=i;
for(ll i=1;i<=tot;i++)
p[Ra[i]]=i;
if(Ra[1]!=1||Ra[tot]!=n)
{
printf("-1");
return 0;
}
for(ll i=1;i<=m;i++)
{
q[p[a[i].r]].push_back(p[a[i].l]);
d[p[a[i].r]].push_back(a[i].c);
}
memset(f,127/3,sizeof(f));
memset(tree,127/3,sizeof(tree));
f[0]=0;
work(1,1,tot,1,0);
for(ll i=2;i<=tot;i++)
{
for(ll j=0;j<q[i].size();j++)
f[i]=min(f[i],change(1,1,tot,q[i][j],i-1)+d[i][j]);
work(1,1,tot,i,f[i]);
}
if(f[tot]>=(ll)1e15)puts("-1"),exit(0);
else cout<<f[tot];
}


//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<limits>
using namespace std;
int n;
int mp[11][11];
char w[10001][55];
char f[10001][55];
char ans[10001][55];
bool flag=false;
void dfs(int num,int now,int limit,bool lim)
{
if(now==limit+1)
{
flag=true;
return;
}
if(!lim)for(int i=9;i>=0;i--)
{
if(mp[f[num][now]-'0'][i] && i<=w[num][now]-'0')
{
ans[num][now]=i+'0';
if(i==w[num][now]-'0')dfs(num,now+1,limit,0);
else dfs(num,now+1,limit,1);
if(flag)return;
}
}
else
{
for(int i=9;i>=0;i--)
{
if(mp[f[num][now]-'0'][i])
{
ans[num][now]=i+'0';
dfs(num,now+1,limit,1);
if(flag)return;
}
}
}
}
int main()
{
freopen("forge.in","r",stdin);
freopen("forge.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s %s",w[i]+1,f[i]+1);
}
for(int i=0;i<=9;i++)
for(int j=0;j<=9;j++)
scanf("%d",&mp[i][j]);
for(int i=0;i<=9;i++)mp[i][i]=1;
for(int i=0;i<=9;i++)
for(int j=0;j<=9;j++)
for(int k=0;k<=9;k++)
mp[j][k]=mp[j][k]||(mp[j][i]&&mp[i][k]);
for(int i=n;i>=1;i--)
{
int len1=strlen(w[i]+1),len2=strlen(f[i]+1),ret=1;
if(len1<len2)puts("NO"),exit(0);
if(len1>len2)
{
for(int p=1;p<=len2;p++)
for(int q=9;q>=0;q--)
if(mp[f[i][p]-'0'][q]==1)
{
ans[i][p]=q+'0';
break;
}
}
else
{
flag=false;
dfs(i,1,len1,0);
if(!flag)puts("NO"),exit(0);
}
if(i==1)break;
len1=strlen(w[i-1]+1);
len2=strlen(ans[i]+1);
if(len1!=len2)ret=(len1>len2)+1;
else
{
for(int j=1;j<=len1;j++)
{
if(ans[i][j]>w[i-1][j]){ret=1;break;}
if(ans[i][j]<w[i-1][j]){ret=2;break;}
}
}
if(ans[i][1]==0)puts("NO"),exit(0);
if(ret==2)for(int j=1;j<=50;j++)w[i-1][j]=ans[i][j];
}
puts("YES");
for(int i=1;i<=n;i++)printf("%s ",ans[i]+1);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: