T1
暴力70
正解DP+贪心(QAQ)
本来写对了,理解错题意了。
DP[i][j]表示跳了i个楼,目前在j楼的最小花费。
首先我们的DP是从1->n的。
那么我们会想顺序会不会产生影响。
显然是会的
比如 1高度3 2为1 3为3
顺序跳显然不如1->3->2优。
所以先把楼按照高度升序或者降序排列。
显然dp[0][i]=c[i]
转移dp[i][j]可以从1->(j-1)中转移而来
dp[i][j]=min(dp[i-1][k]+h[j]-h[k])
最后倒着扫数组,看看<=t的最大i为几.
最后一定要跳到地上。。。。。。。
WTF.
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
struct node{
int h,c;
}a[60];
int n,t,ans;
int dp[60][60];
int abs(int x)
{
if(x<0) x=-x;
return x;
}
bool comp(node x,node y)
{
return x.h<y.h;
}
int main()
{
//freopen("meet.in","r",stdin);
memset(dp,127/3,sizeof(dp));
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i].c);
for(int i=1;i<=n;i++)
scanf("%d",&a[i].h);
scanf("%d",&t);
sort(a+1,a+n+1,comp);
for(int i=1;i<=n;i++) dp[0][i]=a[i].c;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
for(int k=1;k<j;k++)
dp[i][j]=min(dp[i][j],dp[i-1][k]+a[j].h-a[k].h);
dp[i][j]+=a[j].c;
}
for(int i=n;i>=1;i--)
for(int j=1;j<=n;j++)
if(dp[i][j]<=t)
{
printf("%d\n",i+1);
return 0;
}
printf("0");
//printf("%d\n",ans);
return 0;
}
T2 暴力搜索30
正解(我TM也不知道叫啥)
答案为a数组
输入的为b数组。
b数组的顺序不会产生影响。
先把b排序
由于a是升序排列的
显然有
a1+a2=b1
a1+a3=b2
但是 a2+a3=?
无法判断
假设a2+a3=b[x]
我们可以确定出a1,a2,a3的具体值。
然后通过枚举没有被造出来的b与a1来确定一个a值。
再用这个值去筛去可以组合出的b值
这样找,直到找出n个符合条件的数。
字典序?
b从小到大
那么a1就是从大到造出来的。符合要求
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxm=310;
int a[maxm],b[maxm*maxm],ans[maxm][maxm];
int cnt,n,m;
bool used[maxm*maxm];
void get(int x)
{
memset(used,0,sizeof(used));
memset(a,0,sizeof(a));
if((b[1]+b[2]+b[x])%2) return;
a[1]=(b[1]+b[2]+b[x])/2-b[x];
a[2]=b[1]-a[1];
a[3]=b[2]-a[1];
used[1]=used[2]=used[x]=1;
//printf("%d %d %d\n",a[1],a[2],a[3]);
for(int i=4,j=3;i<=n;i++)
{
while(j<=m&&used[j]) j++;
if(j>m) return;
a[i]=b[j]-a[1];
used[j]=1;
for(int k=2;k<i;k++)
{
if(a[k]>a[i]) return;
int B=a[i]+a[k];//造出来的B数
int pos=lower_bound(b+1,b+m+1,B)-b;//第一个位置
if(b[pos]!=B) return;//没这个数返回
int poi=pos;
while(poi<=m&&b[pos]==b[poi]&&used[poi])
poi++;
if(b[poi]!=b[pos]||used[poi]) return;//没找到没变出来过的数
used[poi]=1;
}
}
cnt++;
for(int i=1;i<=n;i++)
ans[cnt][i]=a[i];
}
int main()
{
freopen("city.in","r",stdin);
//freopen("city.out","w",stdout);
scanf("%d",&n);
m=(n*(n-1))/2;
for(int i=1;i<=m;i++)
scanf("%d",b+i);
sort(b+1,b+m+1);
for(int i=3;i<=m;)
{
//printf("%d ",i);
get(i);
int j=i;
while(j<=m&&b[i]==b[j]) j++;
i=j;
}
printf("%d\n",cnt);
for(int i=1;i<=cnt;i++)
{
for(int j=1;j<=n;j++)
printf("%d ",ans[i][j]);
puts("");
}
return 0;
}
T3等待填坑。。。。