dp基础10 -- H

来源:互联网 发布:红米手机怎么清除数据 编辑:程序博客网 时间:2024/06/05 19:17

题意:有k个人要买票(你也在里面最后一位),每个人买票要花时间,或者两个相邻的人一起买会有一个时间, 问你最少花费多少时间才能买到票
思路:
以某个人节点,他要么单独买,要么和前面一个人或者后面一个人一起买,
和后面一个人一起买其实可以看成是后面一个人和他前面的一个人一起买,
因此相当于只有两种情况,要么自己一个人买,要么和前面一个人一起买
于是设计dp[i][0],dp[i][1]
0:代表自己一个人买时到他这个位置所需要的最少时间
1:代表自己和前面一个人一起买到他当前位置所需的最少时间
于是状态转移方程就出来了
dp[i][0] = max(dp[i-1][0], dp[i-1][1]) + t[i]; (i >= 1 && i <= n, t表示单独买所需的时间)
dp[i][1] = max(dp[i-2][0], dp[i-2][1]) + interval[i]; (i >= 2 && i <=n, interval表示和前面一个人一起买所需的时间)
最后的answer就是 max(dp[n][0], dp[n][1])
这个结果是s,换算一下变成时分秒 然后加上早上8点整 大于12点就对12取模,下午是pm,上午是am

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<queue>#include<algorithm>#include<iostream>#include<set>#include<iomanip>using namespace std;int n,m,r,k;int mmax;int a[111111];int tu[1130][1120];struct node{    int speed,weight,id;    bool operator<(const node&t)    {        if(speed==t.speed)            return weight<t.weight;        else            return speed>t.speed;    }}data[9999];int t[10010],dp[11000][3],interval[11100];int main(){    int tt;    cin>>tt;    while(tt--)    {        cin>>n;        for(int i=1;i<=n;i++)            scanf("%d",&t[i]);        for(int i=2;i<=n;i++)            scanf("%d",&interval[i]);       memset(dp,0,sizeof(dp));        for(int i=1;i<=n;i++)        {            dp[i][0] = min(dp[i-1][0],dp[i-1][1])+t[i];            if(i>=2)                dp[i][1]=min(dp[i-2][0],dp[i-2][1])+interval[i];            else                dp[i][1] = t[i];        }        int ans = min(dp[n][0],dp[n][1]);        int h,m,s;        h= ans/3600+8;        ans%=3600;        m = ans/60;        s = ans%60;        if(h>12)        {            h = h%12;            printf("%02d:%02d:%02d pm\n",h,m,s);        }        else        {            printf("%02d:%02d:%02d am\n",h,m,s);        }    }     return 0;}