其他分享
首页 > 其他分享> > DP专辑-codeforces1579-G. Minimal Coverage

DP专辑-codeforces1579-G. Minimal Coverage

作者:互联网

这个题的转移状态不好想:

设f[i][j]为:在第i个数,当前位置与开头位置距离为j时,end位置的最小值

我们不需要确定最左端位置在哪里,只要知道相对位置就好了,可以想做将他们平移到零点

每次更新我们只要枚举和开始节点的长度 j 进行更新,注意到一点特征,ai<=1000,那么距离 j 肯定是 j<=2000的,可以想一下为什么,详细请看代码:

#include<bits/stdc++.h>
using namespace std;
int n,k;
int a[10005];
int dp[10005][2005];
void run()
{
    int n;
    cin>>n;
    for(int i = 0; i<n+2; i++)for(int j =0; j<=2002; j++)dp[i][j]=99999999;

    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
    }
    dp[1][a[1]]=a[1];
    for(int i=2; i<=n; i++)
    {
        for(int j = 0; j<=2000; j++)
        {
            if(a[i]+j<dp[i-1][j])
                dp[i][a[i]+j]=min(dp[i][a[i]+j],dp[i-1][j]);
            else
            {
                if(a[i]+j<=2000)
                    dp[i][a[i]+j]=min(a[i]+j,dp[i][a[i]+j]);
            }
            if(a[i]<j)
            {
                dp[i][j-a[i]]=min(dp[i][j-a[i]],dp[i-1][j]);
            }
            else
            {
                if(a[i]-j+dp[i-1][j]<=2000)
                    dp[i][0]=min(dp[i][0],a[i]-j+dp[i-1][j]);
            }
        }
    }
    int ans =99999999;
    for(int i =0; i<=2000; i++)
    {
        ans=min(ans,dp[n][i]);
    }
    cout<<ans<<endl;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
        run();
    return 0;
}

 

 

标签:10005,codeforces1579,run,int,位置,更新,dp,Coverage,Minimal
来源: https://www.cnblogs.com/4VDP/p/15362541.html