1. 程式人生 > >The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online H Traveling on the Axis ——dp

The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online H Traveling on the Axis ——dp

H Traveling on the Axis BaoBao is taking a walk in the interval [0,n] on the number axis, but he is not free to move, as at every point (i−0.5) for all i∈[1,n], where i is an integer, stands a traffic light of type t ​i (t​i∈{0,1}).

BaoBao decides to begin his walk from point p and end his walk at point q (both p and q are integers, and

p<q). During each unit of time, the following events will happen in order:

Let’s say BaoBao is currently at point x, he will then check the traffic light at point (x+0.5). If the traffic light is green, BaoBao will move to point (x+1); If the traffic light is red, BaoBao will remain at point x. All the traffic lights change their colors. If a traffic light is currently red, it will change to green; If a traffic light is currently green, it will change to red. A traffic light of type 0 is initially red, and a traffic light of type 1 is initially green.

Denote t(p,q) as the total units of time BaoBao needs to move from point p to point q. For some reason, BaoBao wants you to help him calculate

​p=0 ​∑ ​n−1 ​​ ​q=p+1 ​∑ ​n ​​ t(p,q) where both p and q are integers. Can you help him?

Input There are multiple test cases. The first line of the input contains an integer T, indicating the number of test cases. For each test case:

The first and only line contains a string s (1≤∣s∣≤10 ​5 ​​ , ∣s∣=n, s ​i ​​ ∈{‘0’,‘1’} for all 1≤i≤∣s∣), indicating the types of the traffic lights. If s ​i ​​ =‘0’, the traffic light at point (i−0.5) is of type 0 and is initially red; If s ​i ​​ =‘1’, the traffic light at point (i−0.5) is of type 1 and is initially green.

It’s guaranteed that the sum of ∣s∣ of all test cases will not exceed 10 ​6 ​​ .

Output For each test case output one line containing one integer, indicating the answer.

Sample Input 3 101 011 11010 Sample Output 12 15 43 Hint For the first sample test case, it’s easy to calculate that t(0,1)=1, t(0,2)=2, t(0,3)=3, t(1,2)=2, t(1,3)=3 and t(2,3)=1, so the answer is 1+2+3+2+3+1=12.

For the second sample test case, it’s easy to calculate that t(0,1)=2, t(0,2)=3, t(0,3)=5, t(1,2)=1, t(1,3)=3 and t(2,3)=1, so the answer is 2+3+5+1+3+1=15. 題目連結:https://pintia.cn/problem-sets/1036903825309761536/problems/1041156323504345088 題意:從0走到n,0.5,1.5,2.5。。。的位置有紅綠燈,給你一個串,代表初始的每個位置是紅燈還是綠燈,0代表紅燈,1代表綠燈,問你從0走到1,從0走到2。。。從0走到n,從1走到2。。。從1走到n。。。的累加 題解: 我是用了dp,從後往前推,因為後面的狀態是可以記錄下來的而且每個點只有兩個。 dp[0][i]代表第i個狀態的當前狀態,dp[1][i]代表當前狀態的反狀態。 那麼我們可以知道如果當前點為0,那麼我們需要等2秒才到下一個狀態,而下一個狀態就是當前狀態的下一個,就是下一個狀態加上2乘數的個數。如果是1的話,就是下一個狀態的反加上1乘有多少個數舉個例子: 比如說01:一開始是1,那麼dp[0][2]=1,dp[1][2]=2 接下來是0,dp[0][1]=5,dp[1][1]=3 最後全部加起來就好了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
char a[100005];
ll dp[2][100005];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",a+1);
        int n=strlen(a+1);
        if(a[n]=='1')   dp[1][n]=2,dp[0][n]=1;
        else dp[1][n]=1,dp[0][n]=2;
        for(int i=n-1;i>=1;i--)
        {
            if(a[i]=='1')
            {
                dp[0][i]=dp[1][i+1]+n-i+1;
                dp[1][i]=dp[1][i+1]+2*(n-i+1);
            }
            else
            {
                dp[0][i]=dp[0][i+1]+2*(n-i+1);
                dp[1][i]=dp[0][i+1]+n-i+1;
            }
        }
        ll ans=0;
        for(int i=1;i<=n;i++)
            ans+=dp[0][i];//printf("dp[0][%d] = %lld ,dp[1][%d] = %lld\n",i,dp[0][i],i,dp[1][i]),
        printf("%lld\n",ans);
    }
    return 0;
}