bnu4349 精确刷屏工具

拉手网技术骨干小A同鞋在公司做网站测试时,遇到了需要在输入框输入 3000 字的测试用例。一个一个输入肯定是不行的,精通电脑的小A想到,可以利用无敌聊天大法:Ctrl+A、Ctrl+C再Ctrl+V来达到目标。小A平时聊天时经常利用无敌聊天大法生成一大堆笑脸刷屏讨 MM 欢心。通过这个事情,小A联系到一个有趣的问题:假设我们的输入框里只有1个字,要使用无敌聊天大法来达到我们的目标,我们需要最少需要按多少次组合键?
以10个字为例,我们的最优方案如下:
1、 Ctrl+A
2、 Ctrl+C
3、 Ctrl+V
4、 Ctrl+V
5、 Ctrl+V
6、 Ctrl+V
7、 Ctrl+V
8、 Ctrl+A
9、 Ctrl+C
10、Ctrl+V
11、Ctrl+V
最终需要按11次组合键。值得注意的是,在Ctrl+C操作后的第一次Ctrl+V操作,仅仅是覆盖原有文字串。





这道题好像是必须刚好凑成啊。。
我开始以为超过也是可以的啊。。。
如果必须是刚好的话,那么就只有两种方式
dp[i]表示凑i个笑脸需要的最少操作数目。
首先,对i>=2,dp[i]=i+2是成立的,就是ACVVVVVVVV…..疯狂贴就行了。
然后还有更少的可能就是,ACVVVVVVVACVVVVV……这种,比如题目样例。
那么这个第二次ACVV……的时机是什么时候呢?
我们需要暴力枚举一下。
对于每一个j(i%j==0),要不就是先从一个贴,贴到了j个之后,然后j个、j个一起贴,贴i/j+2次。
要不就是先一个一个的贴到i/j个,然后i/j个的、i/j个的一起贴,贴j次,都可以。
然后就转移就好了。

#include
using namespace std;
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define pi(x,y) printf("%d%c",(x),(y));
#define pin(x) printf("%d\n",(x));
#define si(x) scanf("%d",&(x))
#define sii(x,y) scanf("%d%d",&(x),&(y))
#define s3(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))
#define rep(x,y,z) for(int (x)=(y);(x)<(z);++(x))
#define dep(x,y,z) for(int (x)=(y)-1;(x)>=(z);--(x))
#define read int TcaseN;scanf("%d",&TcaseN);for(int Tcase=1;Tcase<=TcaseN;++Tcase)
#define cls(x,y) memset((x),(y),sizeof((x)));
#define pb(x) push_back(x)
#define mp(x,y) make_pair((x),(y))
#define max3(value_a,value_b,value_c) max(max(value_a,value_b),value_c)
#define min3(value_a,value_b,value_c) min(min(value_a,value_b),value_c)
#define GT(x) (x)=clock();
#define fin(x) freopen(x,"r",stdin);
#define fout(x) freopen(x,"w",stdout);

///In This You Can Define Long Integer Type
#define LONGTYPE long long
typedef LONGTYPE LL;
typedef unsigned LONGTYPE ULL;
const int maxint=((~((unsigned)(0)))>>1);
const LL maxll=((~((unsigned LONGTYPE)(0)))>>1);

const int inf=0x3f3f3f3f;
const double PI=acos(-1.0);
const int N=100005;

int dp[N],n;

int main() {
#ifdef tangge
    clock_t tSTART,tEND,t3;
    GT(tSTART);
#endif // tangge

    /*Input:*/
    memset(dp,inf,sizeof(dp));
    dp[0]=dp[1]=0;
    for(int i=2;i2;
        for(int j=2;j*j<=i;++j){
            if(i%j==0){
                dp[i]=min(dp[i],dp[j]+i/j+2);
                dp[i]=min(dp[i],dp[i/j]+j+2);
            }
        }
    }
    int T;scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        printf("%d\n",dp[n]);
    }

#ifdef tangge
    GT(tEND);
    printf("%.8lf\n",(tEND-tSTART)/1000.0);
#endif // tangge
    return 0;
}

你可能感兴趣的:(ACM_dp)